/*******************************************************************************
* Copyright (c) 2007, Angelo Zerr and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - Initial API and implementation
*******************************************************************************/
package org.eclipse.ufacekit.ui.swing.databinding.internal.swing;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComboBox;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import org.eclipse.core.databinding.observable.Diffs;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.core.databinding.observable.list.ListDiff;
/**
* Observe items of Swing JComboBox.
*
* @since 1.0
*/
public class ComboObservableList extends SwingObservableList {
private final JComboBox combo;
private boolean updating;
private List<Object> oldItems;
private ListDataListener listener;
/**
* Create a new observable for the given combo
*
* @param combo
* the combo to observe
* @since 1.0
*/
public ComboObservableList(JComboBox combo) {
super();
this.combo = combo;
initListener();
}
/**
* Create a new observable for the given combo and the given realm
*
* @param realm
* the realm
*
* @param combo
* the combo to observe
*/
public ComboObservableList(Realm realm, JComboBox combo) {
super(realm);
this.combo = combo;
initListener();
}
private void initListener() {
this.listener = new ListDataListener() {
public void intervalAdded(ListDataEvent e) {
fireItemsChanged();
}
public void contentsChanged(ListDataEvent e) {
// Do nothing
}
public void intervalRemoved(ListDataEvent e) {
fireItemsChanged();
}
};
combo.getModel().addListDataListener(listener);
}
protected int getItemCount() {
return combo.getItemCount();
}
protected void setItems(Object[] newItems) {
try {
this.updating = true;
if (newItems != null) {
Object selectedItem = combo.getSelectedItem();
// removeAllItems, setSelectedIndex fire Swing events
// Mark combo in order to ignore the events
// see org.ufacekit.ui.swing.databinding.events.internal.
// SelectionObservableEvent
// which ignore the events if JComboBox is marked as
// COMBOOBSERVABLELIST_SETITEMS.
MarkWidgetUtils.markWidget(combo, MarkWidgetUtils.COMBOOBSERVABLELIST_SETITEMS);
combo.removeAllItems();
for (int i = 0; i < newItems.length; i++) {
combo.addItem(newItems[i]);
}
if (selectedItem != null)
combo.setSelectedItem(selectedItem);
}
// Store old items
oldItems = getItemsAsArray();
} finally {
MarkWidgetUtils.unMarkWidget(combo, MarkWidgetUtils.COMBOOBSERVABLELIST_SETITEMS);
this.updating = false;
}
}
protected Object[] getItems() {
int count = combo.getItemCount();
Object[] items = new Object[count];
for (int i = 0; i < count; i++) {
items[i] = combo.getItemAt(i);
}
return items;
}
private List<Object> getItemsAsArray() {
int count = combo.getItemCount();
List<Object> items = new ArrayList<Object>();
for (int i = 0; i < count; i++) {
items.add(combo.getItemAt(i));
}
return items;
}
protected Object getItem(int index) {
return combo.getItemAt(index);
}
protected void setItem(int index, Object value) {
try {
this.updating = true;
combo.removeItemAt(index);
combo.insertItemAt(value, index);
} finally {
this.updating = false;
}
}
private void fireItemsChanged() {
if (updating)
return;
List<Object> newList = getItemsAsArray();
ListDiff listDiff = Diffs.computeListDiff(oldItems, newList);
fireListChange(listDiff);
oldItems = newList;
}
public synchronized void dispose() {
super.dispose();
combo.getModel().removeListDataListener(listener);
}
}