001 /* Copyright (c) 2008, Henrik Niehaus
002 * All rights reserved.
003 *
004 * Redistribution and use in source and binary forms, with or without
005 * modification, are permitted provided that the following conditions are met:
006 *
007 * 1. Redistributions of source code must retain the above copyright notice,
008 * this list of conditions and the following disclaimer.
009 * 2. Redistributions in binary form must reproduce the above copyright notice,
010 * this list of conditions and the following disclaimer in the documentation
011 * and/or other materials provided with the distribution.
012 * 3. Neither the name of the project nor the names of its
013 * contributors may be used to endorse or promote products derived from this
014 * software without specific prior written permission.
015 *
016 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
017 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
018 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
019 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
020 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
021 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
022 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
023 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
024 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
025 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
026 * POSSIBILITY OF SUCH DAMAGE.
027 */
028 package org.openstreetmap.josm.gui.widgets;
029
030 import java.util.ArrayList;
031 import java.util.Iterator;
032 import java.util.List;
033
034 import javax.swing.DefaultComboBoxModel;
035
036 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
037
038 public class ComboBoxHistory extends DefaultComboBoxModel implements Iterable<AutoCompletionListItem> {
039
040 private int maxSize = 10;
041
042 private List<HistoryChangedListener> listeners = new ArrayList<HistoryChangedListener>();
043
044 public ComboBoxHistory(int size) {
045 maxSize = size;
046 }
047
048 /**
049 * Adds or moves an element to the top of the history
050 */
051 @Override
052 public void addElement(Object o) {
053 if (o instanceof String) {
054 o = new AutoCompletionListItem((String) o);
055 }
056
057 String newEntry = ((AutoCompletionListItem)o).getValue();
058
059 // if history contains this object already, delete it,
060 // so that it looks like a move to the top
061 for (int i = 0; i < getSize(); i++) {
062 String oldEntry = ((AutoCompletionListItem) getElementAt(i)).getValue();
063 if(oldEntry.equals(newEntry)) {
064 removeElementAt(i);
065 }
066 }
067
068 // insert element at the top
069 insertElementAt(o, 0);
070
071 // remove an element, if the history gets too large
072 if(getSize()> maxSize) {
073 removeElementAt(getSize()-1);
074 }
075
076 // set selected item to the one just added
077 setSelectedItem(o);
078
079 fireHistoryChanged();
080 }
081
082 public Iterator<AutoCompletionListItem> iterator() {
083 return new Iterator<AutoCompletionListItem>() {
084
085 private int position = -1;
086
087 public void remove() {
088 removeElementAt(position);
089 }
090
091 public boolean hasNext() {
092 if(position < getSize()-1 && getSize()>0)
093 return true;
094 return false;
095 }
096
097 public AutoCompletionListItem next() {
098 position++;
099 return (AutoCompletionListItem)getElementAt(position);
100 }
101
102 };
103 }
104
105 public void setItemsAsString(List<String> items) {
106 removeAllElements();
107 for (int i = items.size()-1; i>=0; i--) {
108 addElement(new AutoCompletionListItem(items.get(i)));
109 }
110 }
111
112 public List<String> asStringList() {
113 List<String> list = new ArrayList<String>(maxSize);
114 for (AutoCompletionListItem item : this) {
115 list.add(item.getValue());
116 }
117 return list;
118 }
119
120 public void addHistoryChangedListener(HistoryChangedListener l) {
121 listeners.add(l);
122 }
123
124 public void removeHistoryChangedListener(HistoryChangedListener l) {
125 listeners.remove(l);
126 }
127
128 private void fireHistoryChanged() {
129 for (HistoryChangedListener l : listeners) {
130 l.historyChanged(asStringList());
131 }
132 }
133 }