001: /*
002: * Copyright 2006 Ethan Nicholas. All rights reserved.
003: * Use is subject to license terms.
004: */
005: package jaxx.runtime.swing;
006:
007: import java.awt.*;
008: import java.beans.*;
009: import java.util.*;
010: import java.util.List;
011: import javax.swing.*;
012: import javax.swing.event.*;
013:
014: public class JAXXList extends JList {
015: public class JAXXListModel extends AbstractListModel {
016: private List/*<Item>*/items;
017:
018: public JAXXListModel(List/*<Item>*/items) {
019: this .items = items;
020:
021: PropertyChangeListener listener = new PropertyChangeListener() {
022: public void propertyChange(PropertyChangeEvent e) {
023: if (e.getPropertyName().equals(
024: Item.SELECTED_PROPERTY)) {
025: Item item = (Item) e.getSource();
026: int itemIndex = JAXXListModel.this .items
027: .indexOf(item);
028: int[] oldSelection = getSelectedIndices();
029: int[] newSelection;
030: int index = -1;
031: for (int i = 0; i < oldSelection.length; i++) {
032: if (oldSelection[i] == itemIndex) {
033: index = i;
034: break;
035: }
036: }
037: if (item.isSelected()) {
038: if (index != -1) // it was already selected
039: return;
040: newSelection = new int[oldSelection.length + 1];
041: System.arraycopy(oldSelection, 0,
042: newSelection, 0,
043: oldSelection.length);
044: newSelection[newSelection.length - 1] = itemIndex;
045: } else {
046: if (index == -1) // it already wasn't selected
047: return;
048: newSelection = new int[oldSelection.length - 1];
049: System.arraycopy(oldSelection, 0,
050: newSelection, 0, index);
051: System.arraycopy(oldSelection, index + 1,
052: newSelection, index,
053: oldSelection.length - 1 - index);
054: }
055: setSelectedIndices(newSelection);
056: } else {
057: for (int i = 0; i < getSize(); i++) {
058: if (getElementAt(i) == ((Item) e
059: .getSource()).getValue()) {
060: fireContentsChanged(JAXXListModel.this ,
061: i, i);
062: if (isSelectedIndex(i))
063: fireSelectionValueChanged(i, i,
064: false);
065: return;
066: }
067: }
068: }
069: }
070: };
071: for (int i = 0; i < items.size(); i++)
072: ((Item) items.get(i))
073: .addPropertyChangeListener(listener);
074: }
075:
076: public Object getElementAt(int i) {
077: return ((Item) items.get(i)).getValue();
078: }
079:
080: public int getSize() {
081: return items.size();
082: }
083: };
084:
085: public JAXXList() {
086: setCellRenderer(new DefaultListCellRenderer() {
087: public Component getListCellRendererComponent(JList list,
088: Object value, int index, boolean isSelected,
089: boolean cellHasFocus) {
090: ListModel model = list.getModel();
091: if (model instanceof JAXXListModel) {
092: Item item = (Item) ((JAXXListModel) model).items
093: .get(index);
094: String label = item.getLabel();
095: if (label != null)
096: value = label;
097: }
098: return super .getListCellRendererComponent(list, value,
099: index, isSelected, cellHasFocus);
100: }
101: });
102:
103: addListSelectionListener(new ListSelectionListener() {
104: public void valueChanged(ListSelectionEvent e) {
105: ListModel model = getModel();
106: if (model instanceof JAXXListModel) {
107: List/*<Item>*/items = ((JAXXListModel) model).items;
108: for (int i = items.size() - 1; i >= 0; i--) {
109: boolean selected = isSelectedIndex(i);
110: Item item = (Item) items.get(i);
111: if (selected != item.isSelected())
112: item.setSelected(selected);
113: }
114: }
115: }
116: });
117: }
118:
119: // this way we can keep it marked protected and still allow code in this file to call it
120: protected void fireSelectionValueChanged(int firstIndex,
121: int lastIndex, boolean isAdjusting) {
122: super .fireSelectionValueChanged(firstIndex, lastIndex,
123: isAdjusting);
124: }
125:
126: public void setSelectedValue(Object value) {
127: super .setSelectedValue(value, true);
128: }
129:
130: public void setItems(List/*<Item>*/items) {
131: setModel(new JAXXListModel(items));
132: List/*<Integer>*/selectedIndexList = new ArrayList/*<Integer>*/();
133: for (int i = 0; i < items.size(); i++)
134: if (((Item) items.get(i)).isSelected())
135: selectedIndexList.add(new Integer(i));
136: int[] selectedIndices = new int[selectedIndexList.size()];
137: for (int i = 0; i < selectedIndexList.size(); i++)
138: selectedIndices[i] = ((Integer) selectedIndexList.get(i))
139: .intValue();
140: setSelectedIndices(selectedIndices);
141: }
142: }
|