/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc. All rights reserved. Use is
* subject to license terms.
*/
package org.jdesktop.swingbinding.adapters;
import java.beans.*;
import javax.swing.*;
import org.jdesktop.beansbinding.ext.BeanAdapterProvider;
import org.jdesktop.swingbinding.impl.ListBindingManager;
import javax.swing.event.*;
import java.util.List;
import java.util.ArrayList;
/**
* @author Shannon Hickey
*/
public final class JListAdapterProvider implements BeanAdapterProvider {
private static final String SELECTED_ELEMENT_P = "selectedElement";
private static final String SELECTED_ELEMENTS_P = "selectedElements";
private static final String SELECTED_ELEMENT_IA_P = SELECTED_ELEMENT_P + "_IGNORE_ADJUSTING";
private static final String SELECTED_ELEMENTS_IA_P = SELECTED_ELEMENTS_P + "_IGNORE_ADJUSTING";
public final class Adapter extends BeanAdapterBase {
private JList list;
private Handler handler;
private Object cachedElementOrElements;
private Adapter(JList list, String property) {
super(property);
this.list = list;
}
private boolean isPlural() {
return property == SELECTED_ELEMENTS_P || property == SELECTED_ELEMENTS_IA_P;
}
public Object getSelectedElement() {
return JListAdapterProvider.getSelectedElement(list);
}
public Object getSelectedElement_IGNORE_ADJUSTING() {
return getSelectedElement();
}
public List<Object> getSelectedElements() {
return JListAdapterProvider.getSelectedElements(list);
}
public List<Object> getSelectedElements_IGNORE_ADJUSTING() {
return getSelectedElements();
}
protected void listeningStarted() {
handler = new Handler();
cachedElementOrElements = isPlural() ?
getSelectedElements() : getSelectedElement();
list.addPropertyChangeListener("model", handler);
list.addPropertyChangeListener("selectionModel", handler);
list.getSelectionModel().addListSelectionListener(handler);
}
protected void listeningStopped() {
list.getSelectionModel().removeListSelectionListener(handler);
list.removePropertyChangeListener("model", handler);
list.removePropertyChangeListener("selectionModel", handler);
cachedElementOrElements = null;
handler = null;
}
private class Handler implements ListSelectionListener, PropertyChangeListener {
private void listSelectionChanged() {
Object oldElementOrElements = cachedElementOrElements;
cachedElementOrElements = isPlural() ?
getSelectedElements() : getSelectedElement();
firePropertyChange(oldElementOrElements, cachedElementOrElements);
}
public void valueChanged(ListSelectionEvent e) {
if ((property == SELECTED_ELEMENT_IA_P || property == SELECTED_ELEMENTS_IA_P)
&& e.getValueIsAdjusting()) {
return;
}
listSelectionChanged();
}
public void propertyChange(PropertyChangeEvent pce) {
String propertyName = pce.getPropertyName();
if (propertyName == "selectionModel") {
((ListSelectionModel)pce.getOldValue()).removeListSelectionListener(handler);
((ListSelectionModel)pce.getNewValue()).addListSelectionListener(handler);
listSelectionChanged();
} else if (propertyName == "model") {
listSelectionChanged();
}
}
}
}
private static List<Object> getSelectedElements(JList list) {
assert list != null;
ListSelectionModel selectionModel = list.getSelectionModel();
int min = selectionModel.getMinSelectionIndex();
int max = selectionModel.getMaxSelectionIndex();
List<Object> newSelection;
if (min < 0 || max < 0) {
return new ArrayList<Object>(0);
}
ArrayList<Object> elements = new ArrayList<Object>(max - min + 1);
for (int i = min; i <= max; i++) {
if (selectionModel.isSelectedIndex(i)) {
elements.add(getElement(list, i));
}
}
return elements;
}
private static Object getSelectedElement(JList list) {
assert list != null;
// PENDING(shannonh) - more cases to consider
int index = list.getSelectionModel().getLeadSelectionIndex();
index = list.getSelectionModel().isSelectedIndex(index) ?
index : list.getSelectionModel().getMinSelectionIndex();
if (index == -1) {
return null;
}
return getElement(list, index);
}
private static Object getElement(JList list, int index) {
ListModel model = list.getModel();
return model instanceof ListBindingManager ? ((ListBindingManager)model).getElement(index)
: model.getElementAt(index);
}
public boolean providesAdapter(Class<?> type, String property) {
if (!JList.class.isAssignableFrom(type)) {
return false;
}
property = property.intern();
return property == SELECTED_ELEMENT_P ||
property == SELECTED_ELEMENT_IA_P ||
property == SELECTED_ELEMENTS_P ||
property == SELECTED_ELEMENTS_IA_P;
}
public Object createAdapter(Object source, String property) {
if (!providesAdapter(source.getClass(), property)) {
throw new IllegalArgumentException();
}
return new Adapter((JList)source, property);
}
public Class<?> getAdapterClass(Class<?> type) {
return JList.class.isAssignableFrom(type) ?
JListAdapterProvider.Adapter.class :
null;
}
}