All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jfree.ui.KeyedComboBoxModel Maven / Gradle / Ivy

Go to download

jtstand-common is a library derived from jcommon, used by jtstand-chart, which is derived from jfreechart

There is a newer version: 1.5.9
Show newest version
/*
 * Copyright (c) 2009 Albert Kurucz. 
 *
 * This file, KeyedComboBoxModel.java is part of JTStand.
 *
 * JTStand is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JTStand is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with GTStand.  If not, see .
 */
package org.jfree.ui;

import java.util.ArrayList;
import javax.swing.ComboBoxModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

/**
 * The KeyedComboBox model allows to define an internal key (the data element)
 * for every entry in the model.
 * 

* This class is usefull in all cases, where the public text differs from the * internal view on the data. A separation between presentation data and * processing data is a prequesite for localizing combobox entries. This model * does not allow selected elements, which are not in the list of valid * elements. * * @author Thomas Morgner */ public class KeyedComboBoxModel implements ComboBoxModel { /** * The internal data carrier to map keys to values and vice versa. */ private static class ComboBoxItemPair { /** * The key. */ private Object key; /** * The value for the key. */ private Object value; /** * Creates a new item pair for the given key and value. The value can be * changed later, if needed. * * @param key the key * @param value the value */ public ComboBoxItemPair(final Object key, final Object value) { this.key = key; this.value = value; } /** * Returns the key. * * @return the key. */ public Object getKey() { return this.key; } /** * Returns the value. * * @return the value for this key. */ public Object getValue() { return this.value; } /** * Redefines the value stored for that key. * * @param value the new value. */ public void setValue(final Object value) { this.value = value; } } /** * The index of the selected item. */ private int selectedItemIndex; private Object selectedItemValue; /** * The data (contains ComboBoxItemPairs). */ private ArrayList data; /** * The listeners. */ private ArrayList listdatalistener; /** * The cached listeners as array. */ private transient ListDataListener[] tempListeners; private boolean allowOtherValue; /** * Creates a new keyed combobox model. */ public KeyedComboBoxModel() { this.data = new ArrayList(); this.listdatalistener = new ArrayList(); } /** * Creates a new keyed combobox model for the given keys and values. Keys * and values must have the same number of items. * * @param keys the keys * @param values the values */ public KeyedComboBoxModel(final Object[] keys, final Object[] values) { this(); setData(keys, values); } /** * Replaces the data in this combobox model. The number of keys must be * equals to the number of values. * * @param keys the keys * @param values the values */ public void setData(final Object[] keys, final Object[] values) { if (values.length != keys.length) { throw new IllegalArgumentException("Values and text must have the same length."); } this.data.clear(); this.data.ensureCapacity(keys.length); for (int i = 0; i < values.length; i++) { add(keys[i], values[i]); } this.selectedItemIndex = -1; final ListDataEvent evt = new ListDataEvent (this, ListDataEvent.CONTENTS_CHANGED, 0, this.data.size() - 1); fireListDataEvent(evt); } /** * Notifies all registered list data listener of the given event. * * @param evt the event. */ protected synchronized void fireListDataEvent(final ListDataEvent evt) { if (this.tempListeners == null) { this.tempListeners = (ListDataListener[]) this.listdatalistener.toArray (new ListDataListener[this.listdatalistener.size()]); } final ListDataListener[] listeners = this.tempListeners; for (int i = 0; i < listeners.length; i++) { final ListDataListener l = listeners[i]; l.contentsChanged(evt); } } /** * Returns the selected item. * * @return The selected item or null if there is no selection */ public Object getSelectedItem() { return this.selectedItemValue; } /** * Defines the selected key. If the object is not in the list of values, no * item gets selected. * * @param anItem the new selected item. */ public void setSelectedKey(final Object anItem) { if (anItem == null) { this.selectedItemIndex = -1; this.selectedItemValue = null; } else { final int newSelectedItem = findDataElementIndex(anItem); if (newSelectedItem == -1) { this.selectedItemIndex = -1; this.selectedItemValue = null; } else { this.selectedItemIndex = newSelectedItem; this.selectedItemValue = getElementAt(this.selectedItemIndex); } } fireListDataEvent(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, -1, -1)); } /** * Set the selected item. The implementation of this method should notify * all registered ListDataListeners that the contents have * changed. * * @param anItem the list object to select or null to clear the * selection */ public void setSelectedItem(final Object anItem) { if (anItem == null) { this.selectedItemIndex = -1; this.selectedItemValue = null; } else { final int newSelectedItem = findElementIndex(anItem); if (newSelectedItem == -1) { if (isAllowOtherValue()) { this.selectedItemIndex = -1; this.selectedItemValue = anItem; } else { this.selectedItemIndex = -1; this.selectedItemValue = null; } } else { this.selectedItemIndex = newSelectedItem; this.selectedItemValue = getElementAt(this.selectedItemIndex); } } fireListDataEvent(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED, -1, -1)); } private boolean isAllowOtherValue() { return this.allowOtherValue; } /** * @param allowOtherValue */ public void setAllowOtherValue(final boolean allowOtherValue) { this.allowOtherValue = allowOtherValue; } /** * Adds a listener to the list that's notified each time a change to the data * model occurs. * * @param l the ListDataListener to be added */ public synchronized void addListDataListener(final ListDataListener l) { if (l == null) { throw new NullPointerException(); } this.listdatalistener.add(l); this.tempListeners = null; } /** * Returns the value at the specified index. * * @param index the requested index * @return the value at index */ public Object getElementAt(final int index) { if (index >= this.data.size()) { return null; } final ComboBoxItemPair datacon = (ComboBoxItemPair) this.data.get(index); if (datacon == null) { return null; } return datacon.getValue(); } /** * Returns the key from the given index. * * @param index the index of the key. * @return the the key at the specified index. */ public Object getKeyAt(final int index) { if (index >= this.data.size()) { return null; } if (index < 0) { return null; } final ComboBoxItemPair datacon = (ComboBoxItemPair) this.data.get(index); if (datacon == null) { return null; } return datacon.getKey(); } /** * Returns the selected data element or null if none is set. * * @return the selected data element. */ public Object getSelectedKey() { return getKeyAt(this.selectedItemIndex); } /** * Returns the length of the list. * * @return the length of the list */ public int getSize() { return this.data.size(); } /** * Removes a listener from the list that's notified each time a change to * the data model occurs. * * @param l the ListDataListener to be removed */ public void removeListDataListener(final ListDataListener l) { this.listdatalistener.remove(l); this.tempListeners = null; } /** * Searches an element by its data value. This method is called by the * setSelectedItem method and returns the first occurence of the element. * * @param anItem the item * @return the index of the item or -1 if not found. */ private int findDataElementIndex(final Object anItem) { if (anItem == null) { throw new NullPointerException("Item to find must not be null"); } for (int i = 0; i < this.data.size(); i++) { final ComboBoxItemPair datacon = (ComboBoxItemPair) this.data.get(i); if (anItem.equals(datacon.getKey())) { return i; } } return -1; } /** * Tries to find the index of element with the given key. The key must not * be null. * * @param key the key for the element to be searched. * @return the index of the key, or -1 if not found. */ public int findElementIndex(final Object key) { if (key == null) { throw new NullPointerException("Item to find must not be null"); } for (int i = 0; i < this.data.size(); i++) { final ComboBoxItemPair datacon = (ComboBoxItemPair) this.data.get(i); if (key.equals(datacon.getValue())) { return i; } } return -1; } /** * Removes an entry from the model. * * @param key the key */ public void removeDataElement(final Object key) { final int idx = findDataElementIndex(key); if (idx == -1) { return; } this.data.remove(idx); final ListDataEvent evt = new ListDataEvent (this, ListDataEvent.INTERVAL_REMOVED, idx, idx); fireListDataEvent(evt); } /** * Adds a new entry to the model. * * @param key the key * @param cbitem the display value. */ public void add(final Object key, final Object cbitem) { final ComboBoxItemPair con = new ComboBoxItemPair(key, cbitem); this.data.add(con); final ListDataEvent evt = new ListDataEvent (this, ListDataEvent.INTERVAL_ADDED, this.data.size() - 2, this.data.size() - 2); fireListDataEvent(evt); } /** * Removes all entries from the model. */ public void clear() { final int size = getSize(); this.data.clear(); final ListDataEvent evt = new ListDataEvent(this, ListDataEvent.INTERVAL_REMOVED, 0, size - 1); fireListDataEvent(evt); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy