/* * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing; import java.util.*; import java.io.Serializable; /** * A simple implementation of SpinnerModel whose * values are defined by an array or a List. * For example to create a model defined by * an array of the names of the days of the week: *
 * String[] days = new DateFormatSymbols().getWeekdays();
 * SpinnerModel model = new SpinnerListModel(Arrays.asList(days).subList(1, 8));
 * 
* This class only stores a reference to the array or List * so if an element of the underlying sequence changes, it's up * to the application to notify the ChangeListeners by calling * fireStateChanged. *

* This model inherits a ChangeListener. * The ChangeListeners are notified whenever the * model's value or list properties changes. * * @see JSpinner * @see SpinnerModel * @see AbstractSpinnerModel * @see SpinnerNumberModel * @see SpinnerDateModel * * @author Hans Muller * @since 1.4 */ @SuppressWarnings("serial") // Superclass is not serializable across versions public class SpinnerListModel extends AbstractSpinnerModel implements Serializable { private List list; private int index; /** * Constructs a SpinnerModel whose sequence of * values is defined by the specified List. * The initial value (current element) * of the model will be values.get(0). * If values is null or has zero * size, an IllegalArugmentException is thrown. * * @param values the sequence this model represents * @throws IllegalArgumentException if values is * null or zero size */ public SpinnerListModel(List values) { if (values == null || values.size() == 0) { throw new IllegalArgumentException("SpinnerListModel(List) expects non-null non-empty List"); } this.list = values; this.index = 0; } /** * Constructs a SpinnerModel whose sequence of values * is defined by the specified array. The initial value of the model * will be values[0]. If values is * null or has zero length, an * IllegalArgumentException is thrown. * * @param values the sequence this model represents * @throws IllegalArgumentException if values is * null or zero length */ public SpinnerListModel(Object[] values) { if (values == null || values.length == 0) { throw new IllegalArgumentException("SpinnerListModel(Object[]) expects non-null non-empty Object[]"); } this.list = Arrays.asList(values); this.index = 0; } /** * Constructs an effectively empty SpinnerListModel. * The model's list will contain a single * "empty" string element. */ public SpinnerListModel() { this(new Object[]{"empty"}); } /** * Returns the List that defines the sequence for this model. * * @return the value of the list property * @see #setList */ public List getList() { return list; } /** * Changes the list that defines this sequence and resets the index * of the models value to zero. Note that list * is not copied, the model just stores a reference to it. *

* This method fires a ChangeEvent if list is * not equal to the current list. * * @param list the sequence that this model represents * @throws IllegalArgumentException if list is * null or zero length * @see #getList */ public void setList(List list) { if ((list == null) || (list.size() == 0)) { throw new IllegalArgumentException("invalid list"); } if (!list.equals(this.list)) { this.list = list; index = 0; fireStateChanged(); } } /** * Returns the current element of the sequence. * * @return the value property * @see SpinnerModel#getValue * @see #setValue */ public Object getValue() { return list.get(index); } /** * Changes the current element of the sequence and notifies * ChangeListeners. If the specified * value is not equal to an element of the underlying sequence * then an IllegalArgumentException is thrown. * In the following example the setValue call * would cause an exception to be thrown: *

     * String[] values = {"one", "two", "free", "four"};
     * SpinnerModel model = new SpinnerListModel(values);
     * model.setValue("TWO");
     * 
* * @param elt the sequence element that will be model's current value * @throws IllegalArgumentException if the specified value isn't allowed * @see SpinnerModel#setValue * @see #getValue */ public void setValue(Object elt) { int index = list.indexOf(elt); if (index == -1) { throw new IllegalArgumentException("invalid sequence element"); } else if (index != this.index) { this.index = index; fireStateChanged(); } } /** * Returns the next legal value of the underlying sequence or * null if value is already the last element. * * @return the next legal value of the underlying sequence or * null if value is already the last element * @see SpinnerModel#getNextValue * @see #getPreviousValue */ public Object getNextValue() { return (index >= (list.size() - 1)) ? null : list.get(index + 1); } /** * Returns the previous element of the underlying sequence or * null if value is already the first element. * * @return the previous element of the underlying sequence or * null if value is already the first element * @see SpinnerModel#getPreviousValue * @see #getNextValue */ public Object getPreviousValue() { return (index <= 0) ? null : list.get(index - 1); } /** * Returns the next object that starts with substring. * * @param substring the string to be matched * @return the match */ Object findNextMatch(String substring) { int max = list.size(); if (max == 0) { return null; } int counter = index; do { Object value = list.get(counter); String string = value.toString(); if (string != null && string.startsWith(substring)) { return value; } counter = (counter + 1) % max; } while (counter != index); return null; } }