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:
0018: /**
0019: * @author Anton Avtamonov
0020: * @version $Revision$
0021: */package javax.swing;
0022:
0023: import java.awt.Color;
0024: import java.awt.Component;
0025: import java.awt.ComponentOrientation;
0026: import java.awt.Container;
0027: import java.awt.Cursor;
0028: import java.awt.Dimension;
0029: import java.awt.Font;
0030: import java.awt.FontMetrics;
0031: import java.awt.GraphicsEnvironment;
0032: import java.awt.HeadlessException;
0033: import java.awt.Insets;
0034: import java.awt.Point;
0035: import java.awt.Rectangle;
0036: import java.awt.event.FocusListener;
0037: import java.awt.event.MouseEvent;
0038: import java.beans.PropertyChangeEvent;
0039: import java.beans.PropertyChangeListener;
0040: import java.util.Iterator;
0041: import java.util.Locale;
0042: import java.util.Vector;
0043:
0044: import javax.accessibility.Accessible;
0045: import javax.accessibility.AccessibleAction;
0046: import javax.accessibility.AccessibleComponent;
0047: import javax.accessibility.AccessibleContext;
0048: import javax.accessibility.AccessibleIcon;
0049: import javax.accessibility.AccessibleRole;
0050: import javax.accessibility.AccessibleSelection;
0051: import javax.accessibility.AccessibleStateSet;
0052: import javax.accessibility.AccessibleText;
0053: import javax.accessibility.AccessibleValue;
0054: import javax.swing.event.EventListenerList;
0055: import javax.swing.event.ListDataEvent;
0056: import javax.swing.event.ListDataListener;
0057: import javax.swing.event.ListSelectionEvent;
0058: import javax.swing.event.ListSelectionListener;
0059: import javax.swing.plaf.ListUI;
0060: import javax.swing.text.Position;
0061:
0062: import org.apache.harmony.x.swing.StringConstants;
0063: import org.apache.harmony.x.swing.Utilities;
0064:
0065: import org.apache.harmony.x.swing.internal.nls.Messages;
0066:
0067: public class JList extends JComponent implements Scrollable, Accessible {
0068: public static final int VERTICAL = 0;
0069: public static final int VERTICAL_WRAP = 1;
0070: public static final int HORIZONTAL_WRAP = 2;
0071:
0072: private static final String UI_CLASS_ID = "ListUI";
0073:
0074: private static final String CELL_RENDERER_CHANGED_PROPERTY = "cellRenderer";
0075: private static final String FIXED_CELL_HEIGHT_CHANGED_PROPERTY = "fixedCellHeight";
0076: private static final String FIXED_CELL_WIDTH_CHANGED_PROPERTY = "fixedCellWidth";
0077: private static final String MODEL_CHANGED_PROPERTY = "model";
0078: private static final String PROTOTYPE_CELL_VALUE_CHANGED_PROPERTY = "prototypeCellValue";
0079: private static final String SELECTION_BACKGROUND_CHANGED_PROPERTY = "selectionBackground";
0080: private static final String SELECTION_FOREGROUND_CHANGED_PROPERTY = "selectionForeground";
0081: private static final String VISIBLE_ROW_COUNT_CHANGED_PROPERTY = "visibleRowCount";
0082: private static final String LAYOUT_ORIENTATION_CHANGED_PROPERTY = "layoutOrientation";
0083:
0084: private ListModel model;
0085: private ListSelectionModel selectionModel;
0086: private ListCellRenderer cellRenderer;
0087: private EventListenerList selectionListeners = new EventListenerList();
0088: private ListSelectionEventPropagator selectionPropagator = new ListSelectionEventPropagator();
0089: private boolean dragEnabled;
0090: private int fixedCellHeight = -1;
0091: private int fixedCellWidth = -1;
0092: private int layoutOrientation = VERTICAL;
0093: private Object prototypeCellValue;
0094: private Color selectionBackground;
0095: private Color selectionForeground;
0096: private int visibleRowCount = 8;
0097:
0098: //TODO: implement
0099: protected class AccessibleJList extends AccessibleJComponent
0100: implements AccessibleSelection, PropertyChangeListener,
0101: ListSelectionListener, ListDataListener {
0102: protected class AccessibleJListChild extends AccessibleContext
0103: implements Accessible, AccessibleComponent {
0104: private final JList list;
0105: private final int indexInParent;
0106:
0107: private final EventListenerList listenerList = new EventListenerList();
0108:
0109: public AccessibleJListChild(final JList list,
0110: final int indexInParent) {
0111: this .list = list;
0112: this .indexInParent = indexInParent;
0113: }
0114:
0115: public void addFocusListener(final FocusListener l) {
0116: listenerList.add(FocusListener.class, l);
0117: }
0118:
0119: public void removeFocusListener(final FocusListener l) {
0120: listenerList.remove(FocusListener.class, l);
0121: }
0122:
0123: public void addPropertyChangeListener(
0124: final PropertyChangeListener l) {
0125: super .addPropertyChangeListener(l);
0126: }
0127:
0128: public void removePropertyChangeListener(
0129: final PropertyChangeListener l) {
0130: super .removePropertyChangeListener(l);
0131: }
0132:
0133: public boolean contains(final Point p) {
0134: return list.getCellBounds(indexInParent, indexInParent)
0135: .contains(p);
0136: }
0137:
0138: public AccessibleAction getAccessibleAction() {
0139: return super .getAccessibleAction();
0140: }
0141:
0142: public Accessible getAccessibleAt(final Point p) {
0143: return null;
0144: }
0145:
0146: public Accessible getAccessibleChild(final int i) {
0147: return null;
0148: }
0149:
0150: public int getAccessibleChildrenCount() {
0151: return 0;
0152: }
0153:
0154: public AccessibleComponent getAccessibleComponent() {
0155: return this ;
0156: }
0157:
0158: public AccessibleContext getAccessibleContext() {
0159: return this ;
0160: }
0161:
0162: public String getAccessibleDescription() {
0163: return super .getAccessibleDescription();
0164: }
0165:
0166: public void setAccessibleDescription(
0167: final String description) {
0168: super .setAccessibleDescription(description);
0169: }
0170:
0171: public AccessibleIcon[] getAccessibleIcon() {
0172: return new AccessibleIcon[0];
0173: }
0174:
0175: public int getAccessibleIndexInParent() {
0176: return indexInParent;
0177: }
0178:
0179: public String getAccessibleName() {
0180: return super .getAccessibleName();
0181: }
0182:
0183: public void setAccessibleName(final String name) {
0184: super .setAccessibleName(name);
0185: }
0186:
0187: public AccessibleRole getAccessibleRole() {
0188: return AccessibleRole.LIST_ITEM;
0189: }
0190:
0191: public AccessibleSelection getAccessibleSelection() {
0192: return null;
0193: }
0194:
0195: public AccessibleStateSet getAccessibleStateSet() {
0196: return new AccessibleStateSet();
0197: }
0198:
0199: public AccessibleText getAccessibleText() {
0200: return null;
0201: }
0202:
0203: public AccessibleValue getAccessibleValue() {
0204: return null;
0205: }
0206:
0207: public Color getBackground() {
0208: return getRenderingComponent().getBackground();
0209: }
0210:
0211: public void setBackground(final Color c) {
0212:
0213: }
0214:
0215: public Rectangle getBounds() {
0216: return list.getCellBounds(indexInParent, indexInParent);
0217: }
0218:
0219: public void setBounds(final Rectangle r) {
0220:
0221: }
0222:
0223: public Cursor getCursor() {
0224: return getRenderingComponent().getCursor();
0225: }
0226:
0227: public void setCursor(final Cursor c) {
0228:
0229: }
0230:
0231: public void setEnabled(final boolean b) {
0232:
0233: }
0234:
0235: public Font getFont() {
0236: return getRenderingComponent().getFont();
0237: }
0238:
0239: public void setFont(final Font f) {
0240:
0241: }
0242:
0243: public FontMetrics getFontMetrics(final Font f) {
0244: return getRenderingComponent().getFontMetrics(f);
0245: }
0246:
0247: public Color getForeground() {
0248: return getRenderingComponent().getForeground();
0249: }
0250:
0251: public void setForeground(final Color c) {
0252:
0253: }
0254:
0255: public Locale getLocale() {
0256: return list.getLocale();
0257: }
0258:
0259: public Point getLocation() {
0260: return ((JComponent) getRenderingComponent())
0261: .getLocation();
0262: }
0263:
0264: public void setLocation(final Point p) {
0265:
0266: }
0267:
0268: public Point getLocationOnScreen() {
0269: return ((JComponent) getRenderingComponent())
0270: .getLocationOnScreen();
0271: }
0272:
0273: public Dimension getSize() {
0274: return getRenderingComponent().getSize();
0275: }
0276:
0277: public void setSize(final Dimension d) {
0278:
0279: }
0280:
0281: public boolean isEnabled() {
0282: return list.isEnabled();
0283: }
0284:
0285: public boolean isFocusTraversable() {
0286: return true;
0287: }
0288:
0289: public boolean isShowing() {
0290: return list.isShowing();
0291: }
0292:
0293: public void requestFocus() {
0294: }
0295:
0296: public boolean isVisible() {
0297: return list.isVisible();
0298: }
0299:
0300: public void setVisible(final boolean b) {
0301:
0302: }
0303:
0304: private Component getRenderingComponent() {
0305: if (list.getCellRenderer() == null)
0306: return null;
0307: return list.getCellRenderer()
0308: .getListCellRendererComponent(
0309: list,
0310: list.getModel().getElementAt(
0311: indexInParent), indexInParent,
0312: false, false);
0313: }
0314: }
0315:
0316: public AccessibleJList() {
0317: }
0318:
0319: public void contentsChanged(final ListDataEvent e) {
0320:
0321: }
0322:
0323: public void intervalAdded(final ListDataEvent e) {
0324:
0325: }
0326:
0327: public void intervalRemoved(final ListDataEvent e) {
0328:
0329: }
0330:
0331: public Accessible getAccessibleAt(final Point p) {
0332: return JList.this ;
0333: }
0334:
0335: public Accessible getAccessibleChild(final int i) {
0336: return (Accessible) getComponent(i);
0337: }
0338:
0339: public int getAccessibleChildrenCount() {
0340: return getComponentCount();
0341: }
0342:
0343: public AccessibleRole getAccessibleRole() {
0344: return AccessibleRole.LIST;
0345: }
0346:
0347: public void addAccessibleSelection(final int i) {
0348: getAccessibleSelection().addAccessibleSelection(i);
0349: }
0350:
0351: public void clearAccessibleSelection() {
0352: getAccessibleSelection().clearAccessibleSelection();
0353: }
0354:
0355: public AccessibleSelection getAccessibleSelection() {
0356: return null;
0357: }
0358:
0359: public Accessible getAccessibleSelection(final int i) {
0360: return getAccessibleSelection().getAccessibleSelection(i);
0361: }
0362:
0363: public int getAccessibleSelectionCount() {
0364: return getAccessibleSelection()
0365: .getAccessibleSelectionCount();
0366: }
0367:
0368: public boolean isAccessibleChildSelected(final int i) {
0369: return getAccessibleSelection()
0370: .isAccessibleChildSelected(i);
0371: }
0372:
0373: public void removeAccessibleSelection(final int i) {
0374: getAccessibleSelection().removeAccessibleSelection(i);
0375: }
0376:
0377: public void selectAllAccessibleSelection() {
0378: getAccessibleSelection().selectAllAccessibleSelection();
0379: }
0380:
0381: public AccessibleStateSet getAccessibleStateSet() {
0382: return null;
0383: }
0384:
0385: public void propertyChange(final PropertyChangeEvent e) {
0386:
0387: }
0388:
0389: public void valueChanged(final ListSelectionEvent e) {
0390:
0391: }
0392: }
0393:
0394: public JList() {
0395: this (new DefaultListModel());
0396: }
0397:
0398: public JList(final Object[] listData) {
0399: this (new DefaultListModel());
0400: putListData((DefaultListModel) getModel(), listData);
0401: }
0402:
0403: public JList(final Vector<?> listData) {
0404: this (new DefaultListModel());
0405: putListData((DefaultListModel) getModel(), listData);
0406: }
0407:
0408: public JList(final ListModel model) {
0409: if (model == null) {
0410: throw new IllegalArgumentException(Messages
0411: .getString("swing.15")); //$NON-NLS-1$
0412: }
0413: this .model = model;
0414: this .selectionModel = createSelectionModel();
0415: selectionModel.addListSelectionListener(selectionPropagator);
0416: ToolTipManager.sharedInstance().registerComponent(this );
0417:
0418: updateUI();
0419: }
0420:
0421: public void setModel(final ListModel model) {
0422: if (model == null) {
0423: throw new IllegalArgumentException(Messages
0424: .getString("swing.16")); //$NON-NLS-1$
0425: }
0426:
0427: if (this .model != model) {
0428: selectionModel.clearSelection();
0429: ListModel oldValue = this .model;
0430: this .model = model;
0431: firePropertyChange(MODEL_CHANGED_PROPERTY, oldValue, model);
0432: }
0433: }
0434:
0435: public ListModel getModel() {
0436: return model;
0437: }
0438:
0439: public void setSelectionModel(
0440: final ListSelectionModel selectionModel) {
0441: if (selectionModel == null) {
0442: throw new IllegalArgumentException(Messages
0443: .getString("swing.17")); //$NON-NLS-1$
0444: }
0445:
0446: if (this .selectionModel != selectionModel) {
0447: ListSelectionModel oldValue = this .selectionModel;
0448: if (oldValue != null) {
0449: oldValue
0450: .removeListSelectionListener(selectionPropagator);
0451: }
0452: this .selectionModel = selectionModel;
0453: selectionModel
0454: .addListSelectionListener(selectionPropagator);
0455: firePropertyChange(
0456: StringConstants.SELECTION_MODEL_PROPERTY, oldValue,
0457: selectionModel);
0458: }
0459: }
0460:
0461: public ListSelectionModel getSelectionModel() {
0462: return selectionModel;
0463: }
0464:
0465: public void setListData(final Vector<?> listData) {
0466: DefaultListModel defaultModel = new DefaultListModel();
0467: putListData(defaultModel, listData);
0468:
0469: setModel(defaultModel);
0470: }
0471:
0472: public void setListData(final Object[] listData) {
0473: DefaultListModel defaultModel = new DefaultListModel();
0474: putListData(defaultModel, listData);
0475:
0476: setModel(defaultModel);
0477: }
0478:
0479: public String getUIClassID() {
0480: return UI_CLASS_ID;
0481: }
0482:
0483: public void setUI(final ListUI ui) {
0484: super .setUI(ui);
0485: }
0486:
0487: public ListUI getUI() {
0488: return (ListUI) ui;
0489: }
0490:
0491: public void updateUI() {
0492: setUI((ListUI) UIManager.getUI(this ));
0493: }
0494:
0495: public AccessibleContext getAccessibleContext() {
0496: if (accessibleContext == null) {
0497: accessibleContext = new AccessibleJList();
0498: }
0499:
0500: return accessibleContext;
0501: }
0502:
0503: public void setSelectionBackground(final Color selectionBackground) {
0504: if (this .selectionBackground != selectionBackground) {
0505: Color oldValue = this .selectionBackground;
0506: this .selectionBackground = selectionBackground;
0507: firePropertyChange(SELECTION_BACKGROUND_CHANGED_PROPERTY,
0508: oldValue, selectionBackground);
0509: }
0510: }
0511:
0512: public Color getSelectionBackground() {
0513: return selectionBackground;
0514: }
0515:
0516: public void setSelectionForeground(final Color selectionForeground) {
0517: if (this .selectionForeground != selectionForeground) {
0518: Color oldValue = this .selectionForeground;
0519: this .selectionForeground = selectionForeground;
0520: firePropertyChange(SELECTION_FOREGROUND_CHANGED_PROPERTY,
0521: oldValue, selectionForeground);
0522: }
0523: }
0524:
0525: public Color getSelectionForeground() {
0526: return selectionForeground;
0527: }
0528:
0529: public void setCellRenderer(final ListCellRenderer cellRenderer) {
0530: if (this .cellRenderer != cellRenderer) {
0531: ListCellRenderer oldValue = this .cellRenderer;
0532: this .cellRenderer = cellRenderer;
0533: firePropertyChange(CELL_RENDERER_CHANGED_PROPERTY,
0534: oldValue, cellRenderer);
0535: }
0536: }
0537:
0538: public ListCellRenderer getCellRenderer() {
0539: return cellRenderer;
0540: }
0541:
0542: public void setDragEnabled(final boolean dragEnabled) {
0543: if (dragEnabled && GraphicsEnvironment.isHeadless()) {
0544: throw new HeadlessException(Messages.getString("swing.18")); //$NON-NLS-1$
0545: }
0546:
0547: this .dragEnabled = dragEnabled;
0548: }
0549:
0550: public boolean getDragEnabled() {
0551: return dragEnabled;
0552: }
0553:
0554: public void setFixedCellHeight(final int height) {
0555: LookAndFeel.markPropertyNotInstallable(this , "fixedCellHeight");
0556: if (this .fixedCellHeight != height) {
0557: int oldValue = this .fixedCellHeight;
0558: this .fixedCellHeight = height;
0559: firePropertyChange(FIXED_CELL_HEIGHT_CHANGED_PROPERTY,
0560: oldValue, height);
0561: }
0562: }
0563:
0564: public int getFixedCellHeight() {
0565: return fixedCellHeight;
0566: }
0567:
0568: public void setFixedCellWidth(final int width) {
0569: LookAndFeel.markPropertyNotInstallable(this , "fixedCellWidth");
0570: if (this .fixedCellWidth != width) {
0571: int oldValue = this .fixedCellWidth;
0572: this .fixedCellWidth = width;
0573: firePropertyChange(FIXED_CELL_WIDTH_CHANGED_PROPERTY,
0574: oldValue, width);
0575: }
0576: }
0577:
0578: public int getFixedCellWidth() {
0579: return fixedCellWidth;
0580: }
0581:
0582: public void setLayoutOrientation(final int layoutOrientation) {
0583: if (layoutOrientation != VERTICAL
0584: && layoutOrientation != VERTICAL_WRAP
0585: && layoutOrientation != HORIZONTAL_WRAP) {
0586:
0587: throw new IllegalArgumentException(Messages
0588: .getString("swing.19")); //$NON-NLS-1$
0589: }
0590:
0591: if (this .layoutOrientation != layoutOrientation) {
0592: int oldValue = this .layoutOrientation;
0593: this .layoutOrientation = layoutOrientation;
0594: firePropertyChange(LAYOUT_ORIENTATION_CHANGED_PROPERTY,
0595: oldValue, layoutOrientation);
0596: }
0597: }
0598:
0599: public int getLayoutOrientation() {
0600: return layoutOrientation;
0601: }
0602:
0603: public void setPrototypeCellValue(final Object prototypeCellValue) {
0604: if (this .prototypeCellValue != prototypeCellValue) {
0605: Object oldValue = this .prototypeCellValue;
0606: this .prototypeCellValue = prototypeCellValue;
0607: firePropertyChange(PROTOTYPE_CELL_VALUE_CHANGED_PROPERTY,
0608: oldValue, prototypeCellValue);
0609: Dimension prototypePreferredSize = new Dimension(0, 0);
0610: if (getCellRenderer() != null)
0611: prototypePreferredSize = getCellRenderer()
0612: .getListCellRendererComponent(this ,
0613: prototypeCellValue, 0, false, false)
0614: .getPreferredSize();
0615: this .fixedCellWidth = prototypePreferredSize.width;
0616: this .fixedCellHeight = prototypePreferredSize.height;
0617: }
0618: }
0619:
0620: public Object getPrototypeCellValue() {
0621: return prototypeCellValue;
0622: }
0623:
0624: public void setSelectionMode(final int selectionMode) {
0625: selectionModel.setSelectionMode(selectionMode);
0626: }
0627:
0628: public int getSelectionMode() {
0629: return selectionModel.getSelectionMode();
0630: }
0631:
0632: public void setSelectedIndex(final int index) {
0633: selectionModel.setSelectionInterval(index, index);
0634: }
0635:
0636: public int getSelectedIndex() {
0637: return selectionModel.getMinSelectionIndex();
0638: }
0639:
0640: public void setSelectedIndices(final int[] indices) {
0641: clearSelection();
0642: if (indices != null && indices.length > 0) {
0643: for (int i = 0; i < indices.length; i++) {
0644: if (indices[i] >= 0
0645: && indices[i] < getModel().getSize()) {
0646: selectionModel.addSelectionInterval(indices[i],
0647: indices[i]);
0648: }
0649: }
0650: }
0651: }
0652:
0653: public int[] getSelectedIndices() {
0654: int selectionCount = 0;
0655: for (int i = 0; i < model.getSize(); i++) {
0656: if (isSelectedIndex(i)) {
0657: selectionCount++;
0658: }
0659: }
0660:
0661: int[] result = new int[selectionCount];
0662: selectionCount = 0;
0663: for (int i = 0; i < model.getSize(); i++) {
0664: if (isSelectedIndex(i)) {
0665: result[selectionCount++] = i;
0666: }
0667: }
0668:
0669: return result;
0670: }
0671:
0672: public void setSelectedValue(final Object element,
0673: final boolean shouldScroll) {
0674: int index = indexOf(element);
0675: if (index != -1) {
0676: selectionModel.setSelectionInterval(index, index);
0677: if (shouldScroll) {
0678: scrollRectToVisible(getCellBounds(index, index));
0679: }
0680: }
0681: }
0682:
0683: public void setSelectionInterval(final int anchor, final int lead) {
0684: selectionModel.setSelectionInterval(anchor, lead);
0685: }
0686:
0687: public void addSelectionInterval(final int anchor, final int lead) {
0688: selectionModel.addSelectionInterval(anchor, lead);
0689: }
0690:
0691: public void removeSelectionInterval(final int anchor, final int lead) {
0692: selectionModel.removeSelectionInterval(anchor, lead);
0693: }
0694:
0695: public void clearSelection() {
0696: selectionModel.clearSelection();
0697: }
0698:
0699: public int getAnchorSelectionIndex() {
0700: return selectionModel.getAnchorSelectionIndex();
0701: }
0702:
0703: public int getLeadSelectionIndex() {
0704: return selectionModel.getLeadSelectionIndex();
0705: }
0706:
0707: public int getMaxSelectionIndex() {
0708: return selectionModel.getMaxSelectionIndex();
0709: }
0710:
0711: public int getMinSelectionIndex() {
0712: return selectionModel.getMinSelectionIndex();
0713: }
0714:
0715: public Object getSelectedValue() {
0716: int selectedIndex = getSelectedIndex();
0717: if (selectedIndex > -1) {
0718: return model.getElementAt(selectedIndex);
0719: }
0720:
0721: return null;
0722: }
0723:
0724: public Object[] getSelectedValues() {
0725: int[] selectedIndices = getSelectedIndices();
0726: Object[] result = new Object[selectedIndices.length];
0727:
0728: for (int i = 0; i < selectedIndices.length; i++) {
0729: result[i] = model.getElementAt(selectedIndices[i]);
0730: }
0731:
0732: return result;
0733: }
0734:
0735: public boolean isSelectedIndex(final int index) {
0736: return selectionModel.isSelectedIndex(index);
0737: }
0738:
0739: public boolean isSelectionEmpty() {
0740: return selectionModel.isSelectionEmpty();
0741: }
0742:
0743: public void setValueIsAdjusting(final boolean isAdjusting) {
0744: selectionModel.setValueIsAdjusting(isAdjusting);
0745: }
0746:
0747: public boolean getValueIsAdjusting() {
0748: return selectionModel.getValueIsAdjusting();
0749: }
0750:
0751: public void addListSelectionListener(
0752: final ListSelectionListener listener) {
0753: selectionListeners.add(ListSelectionListener.class, listener);
0754: }
0755:
0756: public void removeListSelectionListener(
0757: final ListSelectionListener listener) {
0758: selectionListeners
0759: .remove(ListSelectionListener.class, listener);
0760: }
0761:
0762: public ListSelectionListener[] getListSelectionListeners() {
0763: return (ListSelectionListener[]) selectionListeners
0764: .getListeners(ListSelectionListener.class);
0765: }
0766:
0767: public Point indexToLocation(final int index) {
0768: return ((ListUI) ui).indexToLocation(this , index);
0769: }
0770:
0771: public int locationToIndex(final Point location) {
0772: return ((ListUI) ui).locationToIndex(this , location);
0773: }
0774:
0775: public int getNextMatch(final String prefix, final int startIndex,
0776: final Position.Bias bias) {
0777: return Utilities.getNextMatch(
0778: new Utilities.ListModelAccessor() {
0779: public Object getElementAt(final int index) {
0780: return model.getElementAt(index);
0781: }
0782:
0783: public int getSize() {
0784: return model.getSize();
0785: }
0786:
0787: }, prefix, startIndex, bias);
0788: }
0789:
0790: public Rectangle getCellBounds(final int index0, final int index1) {
0791: return ((ListUI) ui).getCellBounds(this , index0, index1);
0792: }
0793:
0794: public void setVisibleRowCount(final int visibleRowCount) {
0795: LookAndFeel.markPropertyNotInstallable(this , "visibleRowCount");
0796: if (this .visibleRowCount != visibleRowCount) {
0797: int oldValue = this .visibleRowCount;
0798: this .visibleRowCount = visibleRowCount >= 0 ? visibleRowCount
0799: : 0;
0800: firePropertyChange(VISIBLE_ROW_COUNT_CHANGED_PROPERTY,
0801: oldValue, visibleRowCount);
0802: }
0803: }
0804:
0805: public int getVisibleRowCount() {
0806: return visibleRowCount;
0807: }
0808:
0809: public void ensureIndexIsVisible(final int index) {
0810: if (model.getSize() <= index) {
0811: return;
0812: }
0813:
0814: Rectangle cellBounds = getCellBounds(index, index);
0815: if (cellBounds != null) {
0816: scrollRectToVisible(cellBounds);
0817: }
0818: }
0819:
0820: public int getFirstVisibleIndex() {
0821: Rectangle visibleRect = getVisibleRect();
0822: if (visibleRect.isEmpty()) {
0823: return -1;
0824: }
0825:
0826: ComponentOrientation co = getComponentOrientation();
0827: if (co.isHorizontal()) {
0828: for (int i = 0; i < model.getSize(); i++) {
0829: Rectangle bounds = getCellBounds(i, i);
0830: if (bounds.intersects(visibleRect)) {
0831: return i;
0832: }
0833: }
0834: }
0835:
0836: return -1;
0837: }
0838:
0839: public int getLastVisibleIndex() {
0840: Rectangle visibleRect = getVisibleRect();
0841: if (visibleRect.isEmpty()) {
0842: return -1;
0843: }
0844:
0845: ComponentOrientation co = getComponentOrientation();
0846: if (co.isHorizontal()) {
0847: for (int i = model.getSize() - 1; i >= 0; i--) {
0848: Rectangle bounds = getCellBounds(i, i);
0849: if (bounds.intersects(visibleRect)) {
0850: return i;
0851: }
0852: }
0853: }
0854:
0855: return -1;
0856: }
0857:
0858: public Dimension getPreferredScrollableViewportSize() {
0859: if (layoutOrientation != VERTICAL) {
0860: return getPreferredSize();
0861: }
0862:
0863: int height;
0864: if (fixedCellWidth != -1) {
0865: height = fixedCellHeight * visibleRowCount;
0866: } else {
0867: if (model.getSize() > 0) {
0868: Rectangle bounds = getCellBounds(0, 0);
0869: height = bounds.height * visibleRowCount;
0870: } else {
0871: height = 16 * visibleRowCount;
0872: }
0873: }
0874:
0875: int width;
0876: if (fixedCellWidth != -1) {
0877: width = fixedCellWidth;
0878: } else {
0879: if (model.getSize() > 0) {
0880: width = getMaximumCellWidth();
0881: } else {
0882: width = 256;
0883: }
0884: }
0885:
0886: Insets insets = getInsets();
0887: return new Dimension(width + insets.top + insets.bottom, height
0888: + insets.right + insets.left);
0889: }
0890:
0891: public int getScrollableBlockIncrement(final Rectangle visibleRect,
0892: final int orientation, final int direction) {
0893: if (visibleRect == null) {
0894: throw new IllegalArgumentException(Messages
0895: .getString("swing.1A")); //$NON-NLS-1$
0896: }
0897: if (orientation != SwingConstants.VERTICAL
0898: && orientation != SwingConstants.HORIZONTAL) {
0899: throw new IllegalArgumentException(Messages
0900: .getString("swing.1B")); //$NON-NLS-1$
0901: }
0902:
0903: if (orientation == SwingConstants.VERTICAL) {
0904: int result = 0;
0905: if (model.getSize() == 0) {
0906: return visibleRect.height;
0907: }
0908:
0909: if (direction > 0) {
0910: Rectangle bounds = getCellBounds(getLastVisibleIndex(),
0911: getLastVisibleIndex());
0912: if (bounds != null) {
0913: result = visibleRect.height
0914: - bounds.intersection(visibleRect).height;
0915: }
0916: } else {
0917: Rectangle bounds = getCellBounds(
0918: getFirstVisibleIndex(), getFirstVisibleIndex());
0919: if (bounds != null) {
0920: result = visibleRect.height
0921: - bounds.intersection(visibleRect).height;
0922: }
0923: }
0924:
0925: return result > 0 ? result : visibleRect.height;
0926: } else if (orientation == SwingConstants.HORIZONTAL) {
0927: int result = 0;
0928: if (model.getSize() == 0) {
0929: return visibleRect.width;
0930: }
0931:
0932: if (layoutOrientation == JList.VERTICAL_WRAP
0933: || layoutOrientation == JList.HORIZONTAL_WRAP) {
0934: if (direction > 0) {
0935: Rectangle bounds = getCellBounds(
0936: getLastVisibleIndex(),
0937: getLastVisibleIndex());
0938: if (bounds != null) {
0939: result = visibleRect.width
0940: - bounds.intersection(visibleRect).width;
0941: }
0942: } else {
0943: Rectangle bounds = getCellBounds(
0944: getFirstVisibleIndex(),
0945: getFirstVisibleIndex());
0946: if (bounds != null) {
0947: result = visibleRect.width
0948: - bounds.intersection(visibleRect).width;
0949: }
0950: }
0951: }
0952:
0953: return result > 0 ? result : visibleRect.width;
0954: }
0955:
0956: return getScrollableUnitIncrement(visibleRect, orientation,
0957: direction);
0958: }
0959:
0960: public int getScrollableUnitIncrement(final Rectangle visibleRect,
0961: final int orientation, final int direction) {
0962: if (visibleRect == null) {
0963: throw new IllegalArgumentException(Messages
0964: .getString("swing.1A")); //$NON-NLS-1$
0965: }
0966: if (orientation != SwingConstants.VERTICAL
0967: && orientation != SwingConstants.HORIZONTAL) {
0968: throw new IllegalArgumentException(Messages
0969: .getString("swing.1B")); //$NON-NLS-1$
0970: }
0971:
0972: if (orientation == SwingConstants.HORIZONTAL) {
0973: if (getFont() == null) {
0974: return 1;
0975: } else {
0976: return getFont().getSize();
0977: }
0978: } else {
0979: int firstVisibleIndex = getFirstVisibleIndex();
0980: if (firstVisibleIndex == -1) {
0981: return 0;
0982: }
0983: Rectangle firstVisibleBounds = getCellBounds(
0984: firstVisibleIndex, firstVisibleIndex);
0985: int hiddenPart = visibleRect.y - firstVisibleBounds.y;
0986: if (direction > 0) {
0987: return firstVisibleBounds.height - hiddenPart;
0988: } else {
0989: if (hiddenPart == 0) {
0990: if (firstVisibleIndex == 0) {
0991: return 0;
0992: } else {
0993: Rectangle firstInvisibleBounds = getCellBounds(
0994: firstVisibleIndex - 1,
0995: firstVisibleIndex - 1);
0996: return firstInvisibleBounds.height;
0997: }
0998: } else {
0999: return hiddenPart;
1000: }
1001: }
1002: }
1003: }
1004:
1005: public boolean getScrollableTracksViewportHeight() {
1006: Container parent = getParent();
1007: if (!(parent instanceof JViewport)) {
1008: return false;
1009: }
1010:
1011: if (parent.getHeight() > getPreferredSize().height) {
1012: return true;
1013: }
1014: if (layoutOrientation == VERTICAL_WRAP && visibleRowCount <= 0) {
1015: return true;
1016: }
1017:
1018: return false;
1019: }
1020:
1021: public boolean getScrollableTracksViewportWidth() {
1022: Container parent = getParent();
1023: if (!(parent instanceof JViewport)) {
1024: return false;
1025: }
1026:
1027: if (parent.getWidth() > getPreferredSize().width) {
1028: return true;
1029: }
1030: if (layoutOrientation == HORIZONTAL_WRAP
1031: && visibleRowCount <= 0) {
1032: return true;
1033: }
1034:
1035: return false;
1036: }
1037:
1038: public String getToolTipText(final MouseEvent event) {
1039: int index = locationToIndex(event.getPoint());
1040: if (index == -1) {
1041: return super .getToolTipText();
1042: }
1043: if (cellRenderer == null) {
1044: return super .getToolTipText();
1045: }
1046: Component renderer = cellRenderer.getListCellRendererComponent(
1047: this , model.getElementAt(index), index, false, false);
1048: String result = null;
1049: if (renderer instanceof JComponent) {
1050: result = ((JComponent) renderer)
1051: .getToolTipText(SwingUtilities.convertMouseEvent(
1052: this , event, renderer));
1053: }
1054: return result != null ? result : super .getToolTipText();
1055: }
1056:
1057: protected ListSelectionModel createSelectionModel() {
1058: return new DefaultListSelectionModel();
1059: }
1060:
1061: protected void fireSelectionValueChanged(final int firstIndex,
1062: final int lastIndex, final boolean isAdjusting) {
1063: ListSelectionEvent event = new ListSelectionEvent(this ,
1064: firstIndex, lastIndex, isAdjusting);
1065: ListSelectionListener[] listeners = getListSelectionListeners();
1066: for (int i = 0; i < listeners.length; i++) {
1067: listeners[i].valueChanged(event);
1068: }
1069: }
1070:
1071: private int indexOf(final Object element) {
1072: if (model instanceof DefaultListModel) {
1073: return ((DefaultListModel) model).indexOf(element);
1074: } else {
1075: for (int i = 0; i < model.getSize(); i++) {
1076: if (element == null && model.getElementAt(i) == null
1077: || element != null
1078: && element.equals(model.getElementAt(i))) {
1079:
1080: return i;
1081: }
1082: }
1083: }
1084:
1085: return -1;
1086: }
1087:
1088: private int getMaximumCellWidth() {
1089: int result = 0;
1090: if (cellRenderer == null)
1091: return result;
1092: for (int i = 0; i < model.getSize(); i++) {
1093: int width = cellRenderer.getListCellRendererComponent(this ,
1094: model.getElementAt(i), i, false, false)
1095: .getPreferredSize().width;
1096: if (result < width) {
1097: result = width;
1098: }
1099: }
1100:
1101: return result;
1102: }
1103:
1104: private void putListData(final DefaultListModel model,
1105: final Vector listData) {
1106: if (listData != null) {
1107: for (Iterator it = listData.iterator(); it.hasNext();) {
1108: model.addElement(it.next());
1109: }
1110: }
1111: }
1112:
1113: private void putListData(final DefaultListModel model,
1114: final Object[] listData) {
1115: if (listData != null) {
1116: for (int i = 0; i < listData.length; i++) {
1117: model.addElement(listData[i]);
1118: }
1119: }
1120: }
1121:
1122: private class ListSelectionEventPropagator implements
1123: ListSelectionListener {
1124: public void valueChanged(final ListSelectionEvent event) {
1125: fireSelectionValueChanged(event.getFirstIndex(), event
1126: .getLastIndex(), event.getValueIsAdjusting());
1127: }
1128: }
1129: }
|