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 }