Source Code Cross Referenced for BasicListUI.java in  » Apache-Harmony-Java-SE » javax-package » javax » swing » plaf » basic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:        package javax.swing.plaf.basic;
0018:
0019:        import java.awt.Component;
0020:        import java.awt.Dimension;
0021:        import java.awt.Graphics;
0022:        import java.awt.Insets;
0023:        import java.awt.Point;
0024:        import java.awt.Rectangle;
0025:        import java.awt.datatransfer.StringSelection;
0026:        import java.awt.datatransfer.Transferable;
0027:        import java.awt.event.ActionEvent;
0028:        import java.awt.event.ComponentAdapter;
0029:        import java.awt.event.ComponentEvent;
0030:        import java.awt.event.ComponentListener;
0031:        import java.awt.event.FocusEvent;
0032:        import java.awt.event.FocusListener;
0033:        import java.awt.event.KeyAdapter;
0034:        import java.awt.event.KeyEvent;
0035:        import java.awt.event.KeyListener;
0036:        import java.awt.event.MouseEvent;
0037:        import java.beans.PropertyChangeEvent;
0038:        import java.beans.PropertyChangeListener;
0039:
0040:        import javax.swing.AbstractAction;
0041:        import javax.swing.CellRendererPane;
0042:        import javax.swing.JComponent;
0043:        import javax.swing.JList;
0044:        import javax.swing.ListCellRenderer;
0045:        import javax.swing.ListModel;
0046:        import javax.swing.ListSelectionModel;
0047:        import javax.swing.LookAndFeel;
0048:        import javax.swing.SwingUtilities;
0049:        import javax.swing.Timer;
0050:        import javax.swing.TransferHandler;
0051:        import javax.swing.UIManager;
0052:        import javax.swing.event.ListDataEvent;
0053:        import javax.swing.event.ListDataListener;
0054:        import javax.swing.event.ListSelectionEvent;
0055:        import javax.swing.event.ListSelectionListener;
0056:        import javax.swing.event.MouseInputListener;
0057:        import javax.swing.plaf.ComponentUI;
0058:        import javax.swing.plaf.ListUI;
0059:        import javax.swing.plaf.UIResource;
0060:        import javax.swing.text.Position;
0061:
0062:        import org.apache.harmony.x.swing.ExtendedListElement;
0063:        import org.apache.harmony.x.swing.ExtendedListFactory;
0064:        import org.apache.harmony.x.swing.StringConstants;
0065:        import org.apache.harmony.x.swing.Utilities;
0066:
0067:        import org.apache.harmony.x.swing.internal.nls.Messages;
0068:
0069:        public class BasicListUI extends ListUI {
0070:            protected int cellHeight = -1;
0071:            protected int cellWidth = -1;
0072:            protected int[] cellHeights;
0073:            protected JList list;
0074:            protected CellRendererPane rendererPane;
0075:            protected int updateLayoutStateNeeded = modelChanged;
0076:
0077:            protected static final int modelChanged = 1;
0078:            protected static final int selectionModelChanged = 2;
0079:            protected static final int fontChanged = 4;
0080:            protected static final int fixedCellWidthChanged = 8;
0081:            protected static final int fixedCellHeightChanged = 16;
0082:            protected static final int prototypeCellValueChanged = 32;
0083:            protected static final int cellRendererChanged = 64;
0084:            private static final int otherChanged = 128;
0085:
0086:            protected FocusListener focusListener;
0087:            protected ListDataListener listDataListener;
0088:            protected ListSelectionListener listSelectionListener;
0089:            protected MouseInputListener mouseInputListener;
0090:            protected PropertyChangeListener propertyChangeListener;
0091:            private ComponentListener componentListener;
0092:            private KeyListener keyListener;
0093:
0094:            boolean extendedSupportEnabled;
0095:
0096:            final ListLayouter layouter = new ListLayouter();
0097:
0098:            public class FocusHandler implements  FocusListener {
0099:                public void focusGained(final FocusEvent e) {
0100:                    repaintCellFocus();
0101:                }
0102:
0103:                public void focusLost(final FocusEvent e) {
0104:                    repaintCellFocus();
0105:                }
0106:
0107:                protected void repaintCellFocus() {
0108:                    if (list.getLeadSelectionIndex() != -1) {
0109:                        Rectangle bounds = getCellBounds(list, list
0110:                                .getLeadSelectionIndex(), list
0111:                                .getLeadSelectionIndex());
0112:                        if (bounds != null) {
0113:                            list.repaint(bounds);
0114:                        } else {
0115:                            list.repaint();
0116:                        }
0117:                    }
0118:                }
0119:            }
0120:
0121:            public class ListDataHandler implements  ListDataListener {
0122:                public void contentsChanged(final ListDataEvent e) {
0123:                    layouter.reset();
0124:                    list.revalidate();
0125:                    list.repaint();
0126:                }
0127:
0128:                public void intervalAdded(final ListDataEvent e) {
0129:                    list.getSelectionModel().insertIndexInterval(e.getIndex0(),
0130:                            Math.abs(e.getIndex1() - e.getIndex0()) + 1, false);
0131:                    layouter.reset();
0132:                    list.revalidate();
0133:                    list.repaint();
0134:                }
0135:
0136:                public void intervalRemoved(final ListDataEvent e) {
0137:                    list.getSelectionModel().removeIndexInterval(e.getIndex0(),
0138:                            e.getIndex1());
0139:                    layouter.reset();
0140:                    list.revalidate();
0141:                    list.repaint();
0142:                }
0143:            }
0144:
0145:            public class ListSelectionHandler implements  ListSelectionListener {
0146:                public void valueChanged(final ListSelectionEvent e) {
0147:                    repaintCells(e.getFirstIndex(), e.getLastIndex());
0148:                }
0149:            }
0150:
0151:            public class MouseInputHandler implements  MouseInputListener {
0152:                private DnDMouseHelper dndhelper = new DnDMouseHelper(list);
0153:
0154:                public void mousePressed(final MouseEvent e) {
0155:                    if (!SwingUtilities.isLeftMouseButton(e)) {
0156:                        return;
0157:                    }
0158:                    list.requestFocus();
0159:
0160:                    int cellIndex = locationToIndex(list, e.getPoint());
0161:                    dndhelper.mousePressed(e, list.getDragEnabled(),
0162:                            cellIndex != -1, list.isSelectedIndex(cellIndex));
0163:                    if (cellIndex == -1) {
0164:                        return;
0165:                    }
0166:                    if (!list.getDragEnabled()
0167:                            || !list.isSelectedIndex(cellIndex)) {
0168:                        list.getSelectionModel().setValueIsAdjusting(true);
0169:                        processSelection(e, cellIndex);
0170:                    }
0171:                }
0172:
0173:                public void mouseReleased(final MouseEvent e) {
0174:                    dndhelper.mouseReleased(e);
0175:                    if (dndhelper.shouldProcessOnRelease()) {
0176:                        int cellIndex = locationToIndex(list, e.getPoint());
0177:                        if (cellIndex != -1) {
0178:                            processSelection(e, cellIndex);
0179:                        }
0180:                    }
0181:                    list.getSelectionModel().setValueIsAdjusting(false);
0182:                }
0183:
0184:                public void mouseDragged(final MouseEvent e) {
0185:                    dndhelper.mouseDragged(e);
0186:
0187:                    if (!dndhelper.isDndStarted()
0188:                            && SwingUtilities.isLeftMouseButton(e)
0189:                            && !e.isControlDown() && !e.isShiftDown()) {
0190:
0191:                        int cellIndex = locationToIndex(list, e.getPoint());
0192:                        if (cellIndex != -1
0193:                                && list.getLeadSelectionIndex() != cellIndex) {
0194:                            list.getSelectionModel().setValueIsAdjusting(true);
0195:                            list.setSelectedIndex(cellIndex);
0196:                            list.ensureIndexIsVisible(cellIndex);
0197:                        }
0198:                    }
0199:                }
0200:
0201:                public void mouseClicked(final MouseEvent e) {
0202:                }
0203:
0204:                public void mouseEntered(final MouseEvent e) {
0205:                }
0206:
0207:                public void mouseExited(final MouseEvent e) {
0208:                }
0209:
0210:                public void mouseMoved(final MouseEvent e) {
0211:                }
0212:
0213:                private void processSelection(final MouseEvent e,
0214:                        final int cellIndex) {
0215:                    if (e.isControlDown()) {
0216:                        if (list.isSelectedIndex(cellIndex)) {
0217:                            list.removeSelectionInterval(cellIndex, cellIndex);
0218:                        } else {
0219:                            list.addSelectionInterval(cellIndex, cellIndex);
0220:                        }
0221:                    } else if (e.isShiftDown()
0222:                            && list.getAnchorSelectionIndex() != -1) {
0223:                        list.setSelectionInterval(list
0224:                                .getAnchorSelectionIndex(), cellIndex);
0225:                    } else {
0226:                        list.setSelectionInterval(cellIndex, cellIndex);
0227:                    }
0228:                }
0229:            }
0230:
0231:            public class PropertyChangeHandler implements 
0232:                    PropertyChangeListener {
0233:                public void propertyChange(final PropertyChangeEvent event) {
0234:                    String changedProperty = event.getPropertyName();
0235:                    if ("cellRenderer".equals(changedProperty)) {
0236:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0237:                                | cellRendererChanged;
0238:                    } else if ("fixedCellHeight".equals(changedProperty)) {
0239:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0240:                                | fixedCellHeightChanged;
0241:                    } else if ("fixedCellWidth".equals(changedProperty)) {
0242:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0243:                                | fixedCellWidthChanged;
0244:                    } else if ("model".equals(changedProperty)) {
0245:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0246:                                | modelChanged;
0247:                    } else if ("selectionModel".equals(changedProperty)) {
0248:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0249:                                | selectionModelChanged;
0250:                    } else if ("prototypeCellValue".equals(changedProperty)) {
0251:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0252:                                | prototypeCellValueChanged;
0253:                    } else if ("font".equals(changedProperty)) {
0254:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0255:                                | fontChanged;
0256:                    } else if ("visibleRowCount".equals(changedProperty)
0257:                            || "layoutOrientation".equals(changedProperty)
0258:                            || "componentOrientation".equals(changedProperty)
0259:                            || "width".equals(changedProperty)
0260:                            || "height".equals(changedProperty)) {
0261:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0262:                                | otherChanged;
0263:                    } else if (StringConstants.COMPONENT_ORIENTATION
0264:                            .equals(changedProperty)) {
0265:                        uninstallKeyboardActions();
0266:                        installKeyboardActions();
0267:                    }
0268:
0269:                    if ("model".equals(changedProperty)) {
0270:                        ((ListModel) event.getOldValue())
0271:                                .removeListDataListener(listDataListener);
0272:                        ((ListModel) event.getNewValue())
0273:                                .addListDataListener(listDataListener);
0274:                    }
0275:                    if ("selectionModel".equals(changedProperty)) {
0276:                        ((ListSelectionModel) event.getOldValue())
0277:                                .removeListSelectionListener(listSelectionListener);
0278:                        ((ListSelectionModel) event.getNewValue())
0279:                                .addListSelectionListener(listSelectionListener);
0280:                    }
0281:
0282:                    if ("enabled".equals(changedProperty)) {
0283:                        if (((Boolean) event.getNewValue()).booleanValue()) {
0284:                            list.addMouseListener(mouseInputListener);
0285:                            list.addMouseMotionListener(mouseInputListener);
0286:                        } else {
0287:                            list.removeMouseListener(mouseInputListener);
0288:                            list.removeMouseMotionListener(mouseInputListener);
0289:                        }
0290:                    }
0291:
0292:                    if (StringConstants.EXTENDED_SUPPORT_ENABLED_PROPERTY
0293:                            .equals(changedProperty)) {
0294:                        extendedSupportEnabled = ((Boolean) event.getNewValue())
0295:                                .booleanValue();
0296:                        if (extendedSupportEnabled) {
0297:                            list.setCellRenderer(ExtendedListFactory
0298:                                    .getFactory().createExtendedRenderer());
0299:                        } else {
0300:                            list.setCellRenderer((ListCellRenderer) UIManager
0301:                                    .get("List.cellRenderer"));
0302:                        }
0303:                        updateLayoutStateNeeded = updateLayoutStateNeeded
0304:                                | otherChanged;
0305:                    }
0306:
0307:                    list.revalidate();
0308:                    list.repaint();
0309:                }
0310:            }
0311:
0312:            private class ComponentReshapeHandler extends ComponentAdapter {
0313:                @Override
0314:                public void componentResized(final ComponentEvent e) {
0315:                    if (layouter.getLayoutStrategy().isSizeDependent()) {
0316:                        layouter.reset();
0317:                        list.repaint();
0318:                    }
0319:                }
0320:            }
0321:
0322:            private class KeyHandler extends KeyAdapter {
0323:                private StringBuffer searchPrefix = new StringBuffer();
0324:                private Timer searchTimer = new Timer(1000,
0325:                        new AbstractAction() {
0326:                            /**
0327:                             * This class is not guaranteed to be correctly deserialized.
0328:                             */
0329:                            private static final long serialVersionUID = 1L;
0330:
0331:                            public void actionPerformed(final ActionEvent e) {
0332:                                resetSearch();
0333:                            }
0334:                        });
0335:
0336:                @Override
0337:                public void keyTyped(final KeyEvent e) {
0338:                    if (list.getModel().getSize() == 0) {
0339:                        return;
0340:                    }
0341:
0342:                    if (e.getKeyChar() == KeyEvent.CHAR_UNDEFINED) {
0343:                        return;
0344:                    }
0345:                    if ((e.getModifiersEx() & KeyEvent.ALT_DOWN_MASK) != 0
0346:                            || (e.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK) != 0) {
0347:
0348:                        return;
0349:                    }
0350:
0351:                    searchPrefix.append(e.getKeyChar());
0352:
0353:                    int startIndex = list.getSelectedIndex();
0354:                    if (startIndex == -1) {
0355:                        startIndex = 0;
0356:                    }
0357:
0358:                    int nextIndex = getNextMatch(startIndex);
0359:                    if (nextIndex == -1) {
0360:                        if (searchPrefix.length() > 1) {
0361:                            resetSearch();
0362:                            searchPrefix.append(e.getKeyChar());
0363:                            startIndex++;
0364:                            if (startIndex >= list.getModel().getSize()) {
0365:                                startIndex = 0;
0366:                            }
0367:                            nextIndex = getNextMatch(startIndex);
0368:                        }
0369:                    }
0370:                    if (nextIndex != -1) {
0371:                        searchTimer.stop();
0372:                        list.setSelectedIndex(nextIndex);
0373:                        list.ensureIndexIsVisible(nextIndex);
0374:                        searchTimer.restart();
0375:                    } else {
0376:                        resetSearch();
0377:                    }
0378:                }
0379:
0380:                private int getNextMatch(final int startIndex) {
0381:                    int candidateIndex = list.getNextMatch(searchPrefix
0382:                            .toString(), startIndex, Position.Bias.Forward);
0383:                    if (candidateIndex == -1 || !extendedSupportEnabled) {
0384:                        return candidateIndex;
0385:                    }
0386:
0387:                    int firstFoundIndex = candidateIndex;
0388:                    do {
0389:                        Object value = list.getModel().getElementAt(
0390:                                candidateIndex);
0391:                        if (!(value instanceof  ExtendedListElement)
0392:                                || ((ExtendedListElement) value).isChoosable()) {
0393:
0394:                            return candidateIndex;
0395:                        }
0396:                        int nextStartIndex = candidateIndex + 1;
0397:                        if (nextStartIndex == list.getModel().getSize()) {
0398:                            nextStartIndex = 0;
0399:                        }
0400:                        candidateIndex = list.getNextMatch(searchPrefix
0401:                                .toString(), nextStartIndex,
0402:                                Position.Bias.Forward);
0403:                    } while (firstFoundIndex != candidateIndex);
0404:
0405:                    return -1;
0406:                }
0407:
0408:                private void resetSearch() {
0409:                    searchPrefix.delete(0, searchPrefix.length());
0410:                    searchTimer.stop();
0411:                }
0412:            };
0413:
0414:            private class ListTransferHandler extends TransferHandler {
0415:                /**
0416:                 * This class is not guaranteed to be correctly deserialized.
0417:                 */
0418:                private static final long serialVersionUID = -3865101058747175640L;
0419:
0420:                private final String lineSeparator = System
0421:                        .getProperty("line.separator");
0422:
0423:                @Override
0424:                public int getSourceActions(final JComponent c) {
0425:                    return COPY;
0426:                }
0427:
0428:                @Override
0429:                protected Transferable createTransferable(final JComponent c) {
0430:                    Object[] selectedValues = list.getSelectedValues();
0431:                    if (selectedValues == null || selectedValues.length == 0) {
0432:                        return null;
0433:                    }
0434:
0435:                    StringBuffer content = new StringBuffer();
0436:                    for (int i = 0; i < selectedValues.length; i++) {
0437:                        content.append(selectedValues[i]);
0438:                        if (i < selectedValues.length - 1) {
0439:                            content.append(lineSeparator);
0440:                        }
0441:                    }
0442:                    return new StringSelection(content.toString());
0443:                }
0444:            }
0445:
0446:            public static ComponentUI createUI(final JComponent list) {
0447:                return new BasicListUI();
0448:            }
0449:
0450:            @Override
0451:            public Rectangle getCellBounds(final JList list, final int index1,
0452:                    final int index2) {
0453:                layouter.setList(list);
0454:                maybeUpdateLayoutState();
0455:
0456:                Rectangle result = null;
0457:                if (index1 < 0 || index1 >= list.getModel().getSize()
0458:                        || index2 < 0 || index2 >= list.getModel().getSize()) {
0459:
0460:                    return result;
0461:                }
0462:
0463:                if (index1 <= index2) {
0464:                    for (int i = index1; i <= index2; i++) {
0465:                        if (result == null) {
0466:                            result = layouter.getLayoutStrategy().getBounds(i);
0467:                        } else {
0468:                            result.add(layouter.getLayoutStrategy()
0469:                                    .getBounds(i));
0470:                        }
0471:                    }
0472:                } else {
0473:                    for (int i = index2; i <= index1; i++) {
0474:                        if (result == null) {
0475:                            result = layouter.getLayoutStrategy().getBounds(i);
0476:                        } else {
0477:                            result.add(layouter.getLayoutStrategy()
0478:                                    .getBounds(i));
0479:                        }
0480:                    }
0481:                }
0482:
0483:                return result;
0484:            }
0485:
0486:            @Override
0487:            public Dimension getMaximumSize(final JComponent c) {
0488:                return getPreferredSize(c);
0489:            }
0490:
0491:            @Override
0492:            public Dimension getMinimumSize(final JComponent c) {
0493:                return getPreferredSize(c);
0494:            }
0495:
0496:            @Override
0497:            public Dimension getPreferredSize(final JComponent c) {
0498:                maybeUpdateLayoutState();
0499:
0500:                JList list = (JList) c;
0501:                layouter.setList(list);
0502:                return layouter.getLayoutStrategy().getSize();
0503:            }
0504:
0505:            @Override
0506:            public Point indexToLocation(final JList list, final int index) {
0507:                if (index < 0 || index >= list.getModel().getSize()) {
0508:                    return null;
0509:                }
0510:
0511:                layouter.setList(list);
0512:                maybeUpdateLayoutState();
0513:
0514:                Rectangle bounds = getCellBounds(list, index, index);
0515:                return new Point(bounds.x, bounds.y);
0516:            }
0517:
0518:            @Override
0519:            public int locationToIndex(final JList list, final Point location) {
0520:                if (location == null) {
0521:                    throw new NullPointerException();
0522:                }
0523:
0524:                layouter.setList(list);
0525:                maybeUpdateLayoutState();
0526:
0527:                return layouter.getNearestIndex(location);
0528:            }
0529:
0530:            @Override
0531:            public void paint(final Graphics g, final JComponent c) {
0532:                maybeUpdateLayoutState();
0533:
0534:                Rectangle clipRect = g.getClipBounds();
0535:                if (clipRect != null) {
0536:                    for (int i = 0; i < list.getModel().getSize(); i++) {
0537:                        Rectangle bounds = layouter.getLayoutStrategy()
0538:                                .getBounds(i);
0539:                        if (bounds.intersects(clipRect)) {
0540:                            paintCell(g, i, bounds, list.getCellRenderer(),
0541:                                    list.getModel(), list.getSelectionModel(),
0542:                                    i);
0543:                        }
0544:                    }
0545:                } else {
0546:                    for (int i = 0; i < list.getModel().getSize(); i++) {
0547:                        Rectangle bounds = layouter.getLayoutStrategy()
0548:                                .getBounds(i);
0549:                        paintCell(g, i, bounds, list.getCellRenderer(), list
0550:                                .getModel(), list.getSelectionModel(), i);
0551:                    }
0552:                }
0553:            }
0554:
0555:            @Override
0556:            public void installUI(final JComponent c) {
0557:                list = (JList) c;
0558:                rendererPane = new CellRendererPane();
0559:                rendererPane.setVisible(false);
0560:                list.add(rendererPane);
0561:                layouter.setList(list);
0562:
0563:                installDefaults();
0564:                installListeners();
0565:                installKeyboardActions();
0566:            }
0567:
0568:            @Override
0569:            public void uninstallUI(final JComponent c) {
0570:                list = (JList) c;
0571:                list.remove(rendererPane);
0572:                rendererPane = null;
0573:                layouter.setList(null);
0574:
0575:                uninstallDefaults();
0576:                uninstallListeners();
0577:                uninstallKeyboardActions();
0578:            }
0579:
0580:            protected void installDefaults() {
0581:                LookAndFeel.installColorsAndFont(list, "List.background",
0582:                        "List.foreground", "List.font");
0583:                LookAndFeel.installBorder(list, "List.border");
0584:                LookAndFeel.installProperty(list, "opaque", Boolean.TRUE);
0585:
0586:                if ((list.getSelectionBackground() == null)
0587:                        || (list.getSelectionBackground() instanceof  UIResource)) {
0588:                    list.setSelectionBackground(UIManager
0589:                            .getColor("List.selectionBackground"));
0590:                }
0591:                if ((list.getSelectionForeground() == null)
0592:                        || (list.getSelectionForeground() instanceof  UIResource)) {
0593:                    list.setSelectionForeground(UIManager
0594:                            .getColor("List.selectionForeground"));
0595:                }
0596:
0597:                if ((list.getCellRenderer() == null)
0598:                        || (list.getCellRenderer() instanceof  UIResource)) {
0599:                    list.setCellRenderer((ListCellRenderer) UIManager
0600:                            .get("List.cellRenderer"));
0601:                }
0602:
0603:                list.setTransferHandler(new ListTransferHandler());
0604:            }
0605:
0606:            protected void installKeyboardActions() {
0607:                BasicListKeyboardActions.installKeyboardActions(list);
0608:            }
0609:
0610:            protected void installListeners() {
0611:                focusListener = createFocusListener();
0612:                list.addFocusListener(focusListener);
0613:
0614:                listSelectionListener = createListSelectionListener();
0615:                list.getSelectionModel().addListSelectionListener(
0616:                        listSelectionListener);
0617:
0618:                listDataListener = createListDataListener();
0619:                list.getModel().addListDataListener(listDataListener);
0620:
0621:                propertyChangeListener = createPropertyChangeListener();
0622:                list.addPropertyChangeListener(propertyChangeListener);
0623:
0624:                mouseInputListener = createMouseInputListener();
0625:                list.addMouseListener(mouseInputListener);
0626:                list.addMouseMotionListener(mouseInputListener);
0627:
0628:                componentListener = createComponentListener();
0629:                list.addComponentListener(componentListener);
0630:
0631:                keyListener = new KeyHandler();
0632:                list.addKeyListener(keyListener);
0633:            }
0634:
0635:            protected void uninstallDefaults() {
0636:                LookAndFeel.uninstallBorder(list);
0637:                if (list.getCellRenderer() instanceof  UIResource) {
0638:                    list.setCellRenderer(null);
0639:                }
0640:                Utilities.uninstallColorsAndFont(list);
0641:
0642:                list.setTransferHandler(null);
0643:            }
0644:
0645:            protected void uninstallKeyboardActions() {
0646:                BasicListKeyboardActions.uninstallKeyboardActions(list);
0647:            }
0648:
0649:            protected void uninstallListeners() {
0650:                list.removeListSelectionListener(listSelectionListener);
0651:                list.getSelectionModel().removeListSelectionListener(
0652:                        listSelectionListener);
0653:                listSelectionListener = null;
0654:
0655:                list.getModel().removeListDataListener(listDataListener);
0656:                listDataListener = null;
0657:
0658:                list.removeFocusListener(focusListener);
0659:                focusListener = null;
0660:
0661:                list.removePropertyChangeListener(propertyChangeListener);
0662:                propertyChangeListener = null;
0663:
0664:                list.removeMouseListener(mouseInputListener);
0665:                list.removeMouseMotionListener(mouseInputListener);
0666:                mouseInputListener = null;
0667:
0668:                list.removeComponentListener(componentListener);
0669:                componentListener = null;
0670:
0671:                list.removeKeyListener(keyListener);
0672:                keyListener = null;
0673:            }
0674:
0675:            protected void updateLayoutState() {
0676:                layouter.reinit();
0677:            }
0678:
0679:            protected void maybeUpdateLayoutState() {
0680:                if (updateLayoutStateNeeded > 0) {
0681:                    updateLayoutState();
0682:                    updateLayoutStateNeeded = 0;
0683:                }
0684:            }
0685:
0686:            protected void paintCell(final Graphics g, final int row,
0687:                    final Rectangle rowBounds,
0688:                    final ListCellRenderer cellRenderer,
0689:                    final ListModel dataModel,
0690:                    final ListSelectionModel selModel, final int leadIndex) {
0691:                if (list.getCellRenderer() != null) {
0692:                    Component renderer = list
0693:                            .getCellRenderer()
0694:                            .getListCellRendererComponent(
0695:                                    list,
0696:                                    dataModel.getElementAt(row),
0697:                                    row,
0698:                                    selModel.isSelectedIndex(row),
0699:                                    list.isFocusOwner()
0700:                                            && selModel.getLeadSelectionIndex() == row);
0701:                    rendererPane.paintComponent(g, renderer, list, rowBounds.x,
0702:                            rowBounds.y, rowBounds.width, rowBounds.height);
0703:                }
0704:            }
0705:
0706:            protected void selectNextIndex() {
0707:                int currectSelection = list.getMinSelectionIndex();
0708:
0709:                if (currectSelection < list.getModel().getSize() - 1
0710:                        && list.getModel().getSize() > 0) {
0711:                    list.setSelectedIndex(currectSelection + 1);
0712:                    list.ensureIndexIsVisible(currectSelection + 1);
0713:                }
0714:            }
0715:
0716:            protected void selectPreviousIndex() {
0717:                int currectSelection = list.getMinSelectionIndex();
0718:                if (currectSelection > 0) {
0719:                    list.setSelectedIndex(currectSelection - 1);
0720:                    list.ensureIndexIsVisible(currectSelection - 1);
0721:                }
0722:            }
0723:
0724:            protected int getRowHeight(final int row) {
0725:                if (row < 0 || row >= list.getModel().getSize()) {
0726:                    return -1;
0727:                }
0728:
0729:                return layouter.getLayoutStrategy().getBounds(row).height;
0730:            }
0731:
0732:            protected int convertRowToY(final int row) {
0733:                if (row < 0 || row >= list.getModel().getSize()) {
0734:                    return -1;
0735:                }
0736:
0737:                return getCellBounds(list, row, row).y;
0738:            }
0739:
0740:            protected int convertYToRow(final int y) {
0741:                for (int row = 0; row < list.getModel().getSize(); row++) {
0742:                    Rectangle bounds = getCellBounds(list, row, row);
0743:                    if (bounds.y <= y && bounds.y + bounds.height >= y) {
0744:                        return row;
0745:                    }
0746:                }
0747:
0748:                return -1;
0749:            }
0750:
0751:            protected FocusListener createFocusListener() {
0752:                return new FocusHandler();
0753:            }
0754:
0755:            protected ListDataListener createListDataListener() {
0756:                return new ListDataHandler();
0757:            }
0758:
0759:            protected ListSelectionListener createListSelectionListener() {
0760:                return new ListSelectionHandler();
0761:            }
0762:
0763:            protected MouseInputListener createMouseInputListener() {
0764:                return new MouseInputHandler();
0765:            }
0766:
0767:            protected PropertyChangeListener createPropertyChangeListener() {
0768:                return new PropertyChangeHandler();
0769:            }
0770:
0771:            boolean isChoosable(final int index) {
0772:                if (!extendedSupportEnabled) {
0773:                    return true;
0774:                }
0775:                Object value = list.getModel().getElementAt(index);
0776:                return (value instanceof  ExtendedListElement) ? ((ExtendedListElement) value)
0777:                        .isChoosable()
0778:                        : true;
0779:            }
0780:
0781:            private ComponentListener createComponentListener() {
0782:                return new ComponentReshapeHandler();
0783:            }
0784:
0785:            private void repaintCells(final int firstIndex, final int lastIndex) {
0786:                if (firstIndex == -1 || lastIndex == -1) {
0787:                    return;
0788:                }
0789:                int modelSize = list.getModel().getSize();
0790:                int adjustedFirstIndex = firstIndex;
0791:                if (adjustedFirstIndex >= modelSize) {
0792:                    adjustedFirstIndex = modelSize - 1;
0793:                }
0794:                int adjustedLastIndex = lastIndex;
0795:                if (adjustedLastIndex >= modelSize) {
0796:                    adjustedLastIndex = modelSize - 1;
0797:                }
0798:
0799:                Rectangle bounds = getCellBounds(list, adjustedFirstIndex,
0800:                        adjustedLastIndex);
0801:                if (bounds != null) {
0802:                    list.repaint(bounds);
0803:                }
0804:            }
0805:
0806:            interface LayoutStrategy {
0807:                Rectangle getBounds(final int index);
0808:
0809:                int getRow(final int index);
0810:
0811:                int getColumn(final int index);
0812:
0813:                int getIndex(final int row, final int column);
0814:
0815:                int getRowCount();
0816:
0817:                int getColumnCount();
0818:
0819:                Dimension getSize();
0820:
0821:                boolean isSizeDependent();
0822:            }
0823:
0824:            final class ListLayouter {
0825:                private JList list;
0826:                private Insets insets;
0827:                private LayoutStrategy strategy;
0828:                private Insets cachedInsets = new Insets(0, 0, 0, 0);
0829:
0830:                public abstract class AbstractLayoutStrategy implements 
0831:                        LayoutStrategy {
0832:                    public abstract int getRowCount();
0833:
0834:                    public abstract int getColumnCount();
0835:
0836:                    public AbstractLayoutStrategy() {
0837:                        cellWidth = getMaximumWidth();
0838:                        cellHeight = getMaximumHeight();
0839:                        cellHeights = null;
0840:                    }
0841:
0842:                    public Rectangle getBounds(final int index) {
0843:                        return new Rectangle(insets.left + getColumn(index)
0844:                                * cellWidth, insets.top + getRow(index)
0845:                                * cellHeight, cellWidth, cellHeight);
0846:                    }
0847:
0848:                    public Dimension getSize() {
0849:                        Dimension result = new Dimension(getColumnCount()
0850:                                * cellWidth, getRowCount() * cellHeight);
0851:                        return Utilities.addInsets(result, list
0852:                                .getInsets(cachedInsets));
0853:                    }
0854:
0855:                    public boolean isSizeDependent() {
0856:                        return list.getVisibleRowCount() <= 0;
0857:                    }
0858:                }
0859:
0860:                public class VerticalLayoutStategy extends
0861:                        AbstractLayoutStrategy {
0862:                    public VerticalLayoutStategy() {
0863:                        if (list.getFixedCellHeight() <= 0) {
0864:                            cellHeight = -1;
0865:
0866:                            cellHeights = new int[getNumberOfElements()];
0867:                            for (int i = 0; i < getNumberOfElements(); i++) {
0868:                                cellHeights[i] = getPreferredSize(i).height;
0869:                            }
0870:                        }
0871:                    }
0872:
0873:                    @Override
0874:                    public Rectangle getBounds(final int index) {
0875:                        int y = 0;
0876:                        int height = cellHeight;
0877:                        if (cellHeight == -1) {
0878:                            for (int i = 0; i < index; i++) {
0879:                                y += cellHeights[i];
0880:                            }
0881:                            height = cellHeights[index];
0882:                        } else if (index > 0) {
0883:                            y = cellHeight * index;
0884:                        }
0885:
0886:                        return new Rectangle(insets.left, insets.top + y, list
0887:                                .getWidth()
0888:                                - insets.left - insets.right, height);
0889:                    }
0890:
0891:                    public int getRow(final int index) {
0892:                        return index;
0893:                    }
0894:
0895:                    public int getColumn(final int index) {
0896:                        return 0;
0897:                    }
0898:
0899:                    public int getIndex(final int row, final int column) {
0900:                        return row;
0901:                    }
0902:
0903:                    @Override
0904:                    public int getRowCount() {
0905:                        return list.getModel().getSize();
0906:                    }
0907:
0908:                    @Override
0909:                    public int getColumnCount() {
0910:                        return getNumberOfElements() > 0 ? 1 : 0;
0911:                    }
0912:
0913:                    @Override
0914:                    public Dimension getSize() {
0915:                        int height = 0;
0916:                        if (cellHeight == -1) {
0917:                            for (int i = 0; i < getRowCount(); i++) {
0918:                                height += cellHeights[i];
0919:                            }
0920:                        } else {
0921:                            height = cellHeight * getRowCount();
0922:                        }
0923:
0924:                        Dimension result = new Dimension(getColumnCount()
0925:                                * cellWidth, height);
0926:                        return Utilities.addInsets(result, list
0927:                                .getInsets(cachedInsets));
0928:                    }
0929:
0930:                    @Override
0931:                    public boolean isSizeDependent() {
0932:                        return false;
0933:                    }
0934:                }
0935:
0936:                public class VerticalWrapVisibleSpecifiedLayoutStrategy extends
0937:                        AbstractLayoutStrategy {
0938:                    public int getRow(final int index) {
0939:                        return index % getRowCount();
0940:                    }
0941:
0942:                    public int getIndex(final int row, final int column) {
0943:                        return column * getRowCount() + row;
0944:                    }
0945:
0946:                    public int getColumn(final int index) {
0947:                        return index / getRowCount();
0948:                    }
0949:
0950:                    @Override
0951:                    public int getRowCount() {
0952:                        return list.getVisibleRowCount();
0953:                    }
0954:
0955:                    @Override
0956:                    public int getColumnCount() {
0957:                        int modelSize = list.getModel().getSize();
0958:                        return (modelSize == 0 ? 0 : modelSize - 1)
0959:                                / getRowCount() + 1;
0960:                    }
0961:                }
0962:
0963:                public class VerticalWrapVisibleUnspecifiedLayoutStrategy
0964:                        extends AbstractLayoutStrategy {
0965:                    private int maximumNumOfRows;
0966:
0967:                    public VerticalWrapVisibleUnspecifiedLayoutStrategy() {
0968:                        maximumNumOfRows = (list.getHeight() - insets.top - insets.bottom)
0969:                                / cellHeight;
0970:                        if (maximumNumOfRows == 0) {
0971:                            maximumNumOfRows = 1;
0972:                        }
0973:                    }
0974:
0975:                    public int getIndex(final int row, final int column) {
0976:                        return column * getRowCount() + row;
0977:                    }
0978:
0979:                    public int getRow(final int index) {
0980:                        return index % getRowCount();
0981:                    }
0982:
0983:                    public int getColumn(final int index) {
0984:                        return index / getRowCount();
0985:                    }
0986:
0987:                    @Override
0988:                    public int getRowCount() {
0989:                        return maximumNumOfRows;
0990:                    }
0991:
0992:                    @Override
0993:                    public int getColumnCount() {
0994:                        int modelSize = list.getModel().getSize();
0995:                        return (modelSize == 0 ? 0 : modelSize - 1)
0996:                                / getRowCount() + 1;
0997:                    }
0998:                }
0999:
1000:                public class HorizontalWrapVisibleSpecifiedLayoutStrategy
1001:                        extends AbstractLayoutStrategy {
1002:                    public int getRow(final int index) {
1003:                        return index / getColumnCount();
1004:                    }
1005:
1006:                    public int getIndex(final int row, final int column) {
1007:                        return row * getColumnCount() + column;
1008:                    }
1009:
1010:                    public int getColumn(final int index) {
1011:                        return index % getColumnCount();
1012:                    }
1013:
1014:                    @Override
1015:                    public int getRowCount() {
1016:                        return list.getVisibleRowCount();
1017:                    }
1018:
1019:                    @Override
1020:                    public int getColumnCount() {
1021:                        int modelSize = list.getModel().getSize();
1022:                        return (modelSize == 0 ? 0 : modelSize - 1)
1023:                                / getRowCount() + 1;
1024:                    }
1025:                }
1026:
1027:                public class HorizontalWrapVisibleUnspecifiedLayoutStrategy
1028:                        extends AbstractLayoutStrategy {
1029:                    private int maximumNumOfColumns;
1030:
1031:                    public HorizontalWrapVisibleUnspecifiedLayoutStrategy() {
1032:                        maximumNumOfColumns = (list.getWidth() - insets.left - insets.right)
1033:                                / cellWidth;
1034:                        if (maximumNumOfColumns == 0) {
1035:                            maximumNumOfColumns = 1;
1036:                        }
1037:                    }
1038:
1039:                    public int getIndex(final int row, final int column) {
1040:                        return row * getColumnCount() + column;
1041:                    }
1042:
1043:                    public int getRow(final int index) {
1044:                        return index / getColumnCount();
1045:                    }
1046:
1047:                    public int getColumn(final int index) {
1048:                        return index % getColumnCount();
1049:                    }
1050:
1051:                    @Override
1052:                    public int getRowCount() {
1053:                        int modelSize = list.getModel().getSize();
1054:                        return (modelSize == 0 ? 0 : modelSize - 1)
1055:                                / getColumnCount() + 1;
1056:                    }
1057:
1058:                    @Override
1059:                    public int getColumnCount() {
1060:                        return maximumNumOfColumns;
1061:                    }
1062:                }
1063:
1064:                public class OrientationStrategy implements  LayoutStrategy {
1065:                    protected final LayoutStrategy strategy;
1066:
1067:                    public OrientationStrategy(final LayoutStrategy strategy) {
1068:                        this .strategy = strategy;
1069:                    }
1070:
1071:                    public int getIndex(final int row, final int column) {
1072:                        return strategy.getIndex(row, column);
1073:                    }
1074:
1075:                    public int getRowCount() {
1076:                        return strategy.getRowCount();
1077:                    }
1078:
1079:                    public int getColumnCount() {
1080:                        return strategy.getColumnCount();
1081:                    }
1082:
1083:                    public int getRow(final int index) {
1084:                        return strategy.getRow(index);
1085:                    }
1086:
1087:                    public int getColumn(final int index) {
1088:                        return strategy.getColumn(index);
1089:                    }
1090:
1091:                    public Dimension getSize() {
1092:                        return strategy.getSize();
1093:                    }
1094:
1095:                    public Rectangle getBounds(final int index) {
1096:                        return strategy.getBounds(index);
1097:                    }
1098:
1099:                    public boolean isSizeDependent() {
1100:                        return strategy.isSizeDependent();
1101:                    }
1102:                }
1103:
1104:                public class RightToLeftStrategy extends OrientationStrategy {
1105:                    public RightToLeftStrategy(final LayoutStrategy strategy) {
1106:                        super (strategy);
1107:                    }
1108:
1109:                    @Override
1110:                    public Rectangle getBounds(final int index) {
1111:                        Rectangle bounds = strategy.getBounds(index);
1112:                        int x = list.getWidth() - bounds.x - bounds.width;
1113:
1114:                        return new Rectangle(x, bounds.y, bounds.width,
1115:                                bounds.height);
1116:                    }
1117:                }
1118:
1119:                public ListLayouter() {
1120:                    reset();
1121:                }
1122:
1123:                public void setList(final JList list) {
1124:                    if (this .list != list) {
1125:                        this .list = list;
1126:                        reset();
1127:                    }
1128:                }
1129:
1130:                public void reinit() {
1131:                    reset();
1132:                    getLayoutStrategy();
1133:                }
1134:
1135:                public void reset() {
1136:                    strategy = null;
1137:                }
1138:
1139:                public LayoutStrategy getLayoutStrategy() {
1140:                    reinitFields();
1141:                    if (strategy == null) {
1142:                        if (list.getComponentOrientation().isLeftToRight()) {
1143:                            strategy = getStrategy();
1144:                        } else {
1145:                            strategy = new RightToLeftStrategy(getStrategy());
1146:                        }
1147:                    }
1148:
1149:                    return strategy;
1150:                }
1151:
1152:                private LayoutStrategy getStrategy() {
1153:                    LayoutStrategy result;
1154:
1155:                    if (list.getLayoutOrientation() == JList.VERTICAL) {
1156:                        result = new VerticalLayoutStategy();
1157:                    } else if (list.getLayoutOrientation() == JList.VERTICAL_WRAP) {
1158:                        if (list.getVisibleRowCount() > 0) {
1159:                            result = new VerticalWrapVisibleSpecifiedLayoutStrategy();
1160:                        } else {
1161:                            result = new VerticalWrapVisibleUnspecifiedLayoutStrategy();
1162:                        }
1163:                    } else if (list.getLayoutOrientation() == JList.HORIZONTAL_WRAP) {
1164:                        if (list.getVisibleRowCount() > 0) {
1165:                            result = new HorizontalWrapVisibleSpecifiedLayoutStrategy();
1166:                        } else {
1167:                            result = new HorizontalWrapVisibleUnspecifiedLayoutStrategy();
1168:                        }
1169:                    } else {
1170:                        throw new IllegalArgumentException(Messages
1171:                                .getString("swing.70")); //$NON-NLS-1$
1172:                    }
1173:
1174:                    return result;
1175:                }
1176:
1177:                public int getNumberOfElements() {
1178:                    return list.getModel().getSize();
1179:                }
1180:
1181:                public JList getList() {
1182:                    return list;
1183:                }
1184:
1185:                public int getNearestIndex(final Point location) {
1186:                    int result = -1;
1187:                    int distance = Integer.MAX_VALUE;
1188:                    LayoutStrategy s = getLayoutStrategy();
1189:                    for (int i = 0; i < getNumberOfElements(); i++) {
1190:                        Rectangle bounds = s.getBounds(i);
1191:                        int d = getDistance(bounds, location);
1192:                        if (distance > d) {
1193:                            distance = d;
1194:                            result = i;
1195:                        }
1196:                    }
1197:
1198:                    return result;
1199:                }
1200:
1201:                private void reinitFields() {
1202:                    insets = list.getInsets(cachedInsets);
1203:                }
1204:
1205:                private int getMaximumWidth() {
1206:                    if (list.getFixedCellWidth() >= 0) {
1207:                        return list.getFixedCellWidth();
1208:                    }
1209:
1210:                    int result = -1;
1211:                    for (int i = 0; i < list.getModel().getSize(); i++) {
1212:                        Dimension size = getPreferredSize(i);
1213:                        if (result < size.width) {
1214:                            result = size.width;
1215:                        }
1216:                    }
1217:                    return result;
1218:                }
1219:
1220:                private int getMaximumHeight() {
1221:                    if (list.getFixedCellHeight() >= 0) {
1222:                        return list.getFixedCellHeight();
1223:                    }
1224:
1225:                    int result = -1;
1226:                    for (int i = 0; i < list.getModel().getSize(); i++) {
1227:                        Dimension size = getPreferredSize(i);
1228:                        if (result < size.height) {
1229:                            result = size.height;
1230:                        }
1231:                    }
1232:                    return result;
1233:                }
1234:
1235:                private Dimension getPreferredSize(final int i) {
1236:                    if (list.getCellRenderer() == null) {
1237:                        return new Dimension(0, 0);
1238:                    }
1239:                    return list.getCellRenderer().getListCellRendererComponent(
1240:                            list, list.getModel().getElementAt(i), i, false,
1241:                            false).getPreferredSize();
1242:                }
1243:
1244:                private int getDistance(final Rectangle r, final Point p) {
1245:                    int dx = 0;
1246:                    if (p.x < r.x) {
1247:                        dx = r.x - p.x;
1248:                    } else if (p.x > r.x + r.width) {
1249:                        dx = p.x - r.x - r.width;
1250:                    } else {
1251:                        dx = 0;
1252:                    }
1253:
1254:                    int dy = 0;
1255:                    if (p.y < r.y) {
1256:                        dy = r.y - p.y;
1257:                    } else if (p.y > r.y + r.height) {
1258:                        dy = p.y - r.y - r.height;
1259:                    } else {
1260:                        dy = 0;
1261:                    }
1262:
1263:                    return dx + dy;
1264:                }
1265:            }
1266:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.