diff --git a/src/org/openstreetmap/josm/gui/widgets/ComboBoxHistory.java b/src/org/openstreetmap/josm/gui/widgets/ComboBoxHistory.java
index e1238016a6..f7a70a7cf4 100644
|
a
|
b
|
class ComboBoxHistory extends DefaultComboBoxModel<AutoCompletionItem> implement
|
| 41 | 41 | public void addElement(AutoCompletionItem o) { |
| 42 | 42 | String newEntry = o.getValue(); |
| 43 | 43 | |
| | 44 | boolean alreadyAdded = false; |
| 44 | 45 | // if history contains this object already, delete it, |
| 45 | 46 | // so that it looks like a move to the top |
| 46 | 47 | for (int i = 0; i < getSize(); i++) { |
| 47 | 48 | String oldEntry = getElementAt(i).getValue(); |
| 48 | 49 | if (oldEntry.equals(newEntry)) { |
| 49 | | removeElementAt(i); |
| | 50 | if (i == 0) { |
| | 51 | alreadyAdded = true; |
| | 52 | break; |
| | 53 | } else { |
| | 54 | removeElementAt(i); |
| | 55 | } |
| 50 | 56 | } |
| 51 | 57 | } |
| 52 | 58 | |
| 53 | | // insert element at the top |
| 54 | | insertElementAt(o, 0); |
| | 59 | if (!alreadyAdded) { |
| | 60 | // insert element at the top |
| | 61 | insertElementAt(o, 0); |
| | 62 | } |
| 55 | 63 | |
| 56 | 64 | // remove an element, if the history gets too large |
| 57 | 65 | if (getSize() > maxSize) { |
diff --git a/src/org/openstreetmap/josm/gui/widgets/HistoryComboBox.java b/src/org/openstreetmap/josm/gui/widgets/HistoryComboBox.java
index dc6955ece1..33de5a32ac 100644
|
a
|
b
|
import java.util.List;
|
| 5 | 5 | |
| 6 | 6 | import javax.swing.text.JTextComponent; |
| 7 | 7 | |
| | 8 | import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem; |
| 8 | 9 | import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox; |
| 9 | 10 | import org.openstreetmap.josm.spi.preferences.Config; |
| 10 | 11 | |
| … |
… |
public class HistoryComboBox extends AutoCompletingComboBox {
|
| 54 | 55 | * @see ComboBoxHistory#addElement(java.lang.String) |
| 55 | 56 | */ |
| 56 | 57 | public void addCurrentItemToHistory() { |
| 57 | | model.addElement(getEditor().getItem().toString()); |
| | 58 | Object item = getEditor().getItem(); |
| | 59 | // This avoids instantiating multiple AutoCompletionItems |
| | 60 | if (item instanceof AutoCompletionItem) { |
| | 61 | model.addElement((AutoCompletionItem) item); |
| | 62 | } else { |
| | 63 | model.addElement(item.toString()); |
| | 64 | } |
| 58 | 65 | } |
| 59 | 66 | |
| 60 | 67 | /** |
diff --git a/test/unit/org/openstreetmap/josm/gui/widgets/HistoryComboBoxTest.java b/test/unit/org/openstreetmap/josm/gui/widgets/HistoryComboBoxTest.java
index 6475b5d1bd..dcdae47eb2 100644
|
a
|
b
|
class HistoryComboBoxTest {
|
| 44 | 44 | historyComboBox.getEditor().setItem(null); |
| 45 | 45 | assertDoesNotThrow(historyComboBox::addCurrentItemToHistory); |
| 46 | 46 | } |
| | 47 | |
| | 48 | /** |
| | 49 | * Non-regression test for JOSM #21215: StackOverflowError |
| | 50 | */ |
| | 51 | @Test |
| | 52 | void testNonRegression21215() { |
| | 53 | final HistoryComboBox historyComboBox = new HistoryComboBox(); |
| | 54 | // utils plugin2 added a listener that pretty much did this |
| | 55 | historyComboBox.addItemListener(event -> historyComboBox.addCurrentItemToHistory()); |
| | 56 | final AutoCompletionItem testItem = new AutoCompletionItem("testNonRegression21215"); |
| | 57 | // Add the original item |
| | 58 | historyComboBox.getEditor().setItem(testItem); |
| | 59 | historyComboBox.addCurrentItemToHistory(); |
| | 60 | |
| | 61 | // add a new item |
| | 62 | historyComboBox.getEditor().setItem(new AutoCompletionItem("testNonRegression21215_2")); |
| | 63 | historyComboBox.addCurrentItemToHistory(); |
| | 64 | |
| | 65 | // Readd the first item |
| | 66 | historyComboBox.getEditor().setItem(testItem); |
| | 67 | assertDoesNotThrow(historyComboBox::addCurrentItemToHistory); |
| | 68 | } |
| 47 | 69 | } |