Java/Swing JFC/Spinner

Материал из Java эксперт
Перейти к: навигация, поиск

A date spinner

   <source lang="java">
 

import java.util.Calendar; import java.util.GregorianCalendar; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; public class Main {

 public static void main(String[] argv) throws Exception {
   SpinnerDateModel dateModel = new SpinnerDateModel();
   JSpinner spinner = new JSpinner(dateModel);
   Calendar calendar = new GregorianCalendar(2000, Calendar.JANUARY, 1);
   spinner.setValue(calendar.getTime());
 }

}


 </source>
   
  
 
  



A list spinner

   <source lang="java">
 

import javax.swing.JSpinner; import javax.swing.SpinnerListModel; public class Main {

 public static void main(String[] argv) throws Exception {
   SpinnerListModel listModel = new SpinnerListModel(new String[] { "red","green", "blue" });
   JSpinner spinner = new JSpinner(listModel);
   spinner.setValue("blue");
 }

}


 </source>
   
  
 
  



An example of JSpinner with a custom editor

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// MonthSpinner.java //An example of JSpinner with a custom editor that allows the user to spin //through dates of the mm/yy format. // import java.awt.Container; import java.awt.FlowLayout; import java.util.Calendar; import java.util.Date; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; public class MonthSpinner extends JFrame {

 public MonthSpinner() {
   super("Month Spinner");
   setSize(200, 100);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   Container c = getContentPane();
   c.setLayout(new FlowLayout(FlowLayout.LEFT, 4, 4));
   c.add(new JLabel("Expiration Date:"));
   Date today = new Date();
   // Start the spinner today, but don"t set a min or max date
   // The increment should be a month
   JSpinner s = new JSpinner(new SpinnerDateModel(today, null, null,
       Calendar.MONTH));
   JSpinner.DateEditor de = new JSpinner.DateEditor(s, "MM/yy");
   s.setEditor(de);
   c.add(s);
   setVisible(true);
 }
 public static void main(String args[]) {
   new MonthSpinner();
 }

}


 </source>
   
  
 
  



An implementation of JSpinner with customized content--icons

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// IconSpinner.java //An implementation of JSpinner with customized content--icons in this case. //A standard spinner model is used with a custom editor (IconEditor.java). // import java.awt.Container; import java.awt.GridLayout; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerListModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class IconSpinner extends JFrame {

 public IconSpinner() {
   super("JSpinner Icon Test");
   setSize(300, 80);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   Container c = getContentPane();
   c.setLayout(new GridLayout(0, 2));
   Icon nums[] = new Icon[] { new ImageIcon("1.gif"),
       new ImageIcon("2.gif"), new ImageIcon("3.gif"),
       new ImageIcon("4.gif"), new ImageIcon("5.gif"),
       new ImageIcon("6.gif") };
   JSpinner s1 = new JSpinner(new SpinnerListModel(nums));
   s1.setEditor(new IconEditor(s1));
   c.add(new JLabel(" Icon Spinner"));
   c.add(s1);
   setVisible(true);
 }
 public static void main(String args[]) {
   new IconSpinner();
 }

} class IconEditor extends JLabel implements ChangeListener {

 JSpinner spinner;
 Icon icon;
 public IconEditor(JSpinner s) {
   super((Icon) s.getValue(), CENTER);
   icon = (Icon) s.getValue();
   spinner = s;
   spinner.addChangeListener(this);
 }
 public void stateChanged(ChangeEvent ce) {
   icon = (Icon) spinner.getValue();
   setIcon(icon);
 }
 public JSpinner getSpinner() {
   return spinner;
 }
 public Icon getIcon() {
   return icon;
 }

}


 </source>
   
  
 
  



A quick test of various spinners

   <source lang="java">
 

/* Java Swing, 2nd Edition By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole ISBN: 0-596-00408-7 Publisher: O"Reilly

  • /

// SwingSpinnerTest.java //A quick test of various spinners. // import java.awt.Container; import java.awt.GridLayout; import java.util.List; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; import javax.swing.SpinnerListModel; import javax.swing.SpinnerNumberModel; public class SwingSpinnerTest extends JFrame {

 public SwingSpinnerTest() {
   super("JSpinner Test");
   setSize(300, 180);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   Container c = getContentPane();
   c.setLayout(new GridLayout(0, 2));
   c.add(new JLabel(" Basic Spinner"));
   c.add(new JSpinner());
   c.add(new JLabel(" Date Spinner"));
   c.add(new JSpinner(new SpinnerDateModel()));
   String weekdays[] = new String[] { "Sunday", "Monday", "Tuesday",
       "Wednesday", "Thursday", "Friday", "Saturday" };
   c.add(new JLabel(" List Spinner"));
   c.add(new JSpinner(new SpinnerListModel(weekdays)));
   c.add(new JLabel(" Number Spinner"));
   c.add(new JSpinner(new SpinnerNumberModel(0, 0, 100, 5)));
   c.add(new JLabel(" Rollover List Spinner"));
   c.add(new JSpinner(new RolloverSpinnerListModel(weekdays)));
   setVisible(true);
 }
 public static void main(String args[]) {
   new SwingSpinnerTest();
 }

} class RolloverSpinnerListModel extends SpinnerListModel {

 public RolloverSpinnerListModel(Object[] items) {
   super(items);
 }
 public RolloverSpinnerListModel(List items) {
   super(items);
 }
 public Object getNextValue() {
   Object nv = super.getNextValue();
   if (nv != null) {
     return nv;
   }
   return getList().get(0);
 }
 public Object getPreviousValue() {
   Object pv = super.getPreviousValue();
   if (pv != null) {
     return pv;
   }
   List l = getList();
   return l.get(l.size() - 1);
 }

}


 </source>
   
  
 
  



A spinner of dates

   <source lang="java">
 

import java.awt.FlowLayout; import java.util.Calendar; import java.util.Date; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; public class Main extends JFrame {

 public Main () {
   setSize(200, 100);
   setDefaultCloseOperation(EXIT_ON_CLOSE);
   setLayout(new FlowLayout(FlowLayout.LEFT, 4, 4));
   add(new JLabel("Expiration Date:"));
   Date today = new Date();
   JSpinner s = new JSpinner(new SpinnerDateModel(today, null, null, Calendar.MONTH));
   JSpinner.DateEditor de = new JSpinner.DateEditor(s, "MM/yy");
   s.setEditor(de);
   add(s);
   setVisible(true);
 }
 public static void main(String args[]) {
   new Main();
 }

}


 </source>
   
  
 
  



Create a spinner

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.plaf.basic.BasicArrowButton; public class Spinner extends JPanel {

 private int orientation = SwingConstants.VERTICAL;
 private BasicArrowButton incrementButton;
 private BasicArrowButton decrementButton;
 public Spinner() {
   createComponents();
 }
 public Spinner(int o) {
   orientation = o;
   createComponents();
 }
 public void setEnabled(boolean enable) {
   incrementButton.setEnabled(enable);
   decrementButton.setEnabled(enable);
 }
 public boolean isEnabled() {
   return (incrementButton.isEnabled() && decrementButton.isEnabled());
 }
 protected void createComponents() {
   if (orientation == SwingConstants.VERTICAL) {
     setLayout(new GridLayout(2, 1));
     incrementButton = new BasicArrowButton(SwingConstants.NORTH);
     decrementButton = new BasicArrowButton(SwingConstants.SOUTH);
     add(incrementButton);
     add(decrementButton);
   } else if (orientation == SwingConstants.HORIZONTAL) {
     setLayout(new GridLayout(1, 2));
     incrementButton = new BasicArrowButton(SwingConstants.EAST);
     decrementButton = new BasicArrowButton(SwingConstants.WEST);
     add(decrementButton);
     add(incrementButton);
   }
 }
 public JButton getIncrementButton() {
   return (incrementButton);
 }
 public JButton getDecrementButton() {
   return (decrementButton);
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame();
   JPanel panel = (JPanel) frame.getContentPane();
   panel.setLayout(new BorderLayout());
   JTextField field = new JTextField(20);
   Spinner spinner = new Spinner();
   panel.add(field, "Center");
   panel.add(spinner, "East");
   Dimension dim = frame.getToolkit().getScreenSize();
   frame.setLocation(dim.width / 2 - frame.getWidth() / 2, dim.height / 2
       - frame.getHeight() / 2);
   frame.pack();
   frame.show();
 }

}



 </source>
   
  
 
  



Creating a JSpinner Component: A number spinner:

   <source lang="java">
 

import javax.swing.JSpinner; public class Main {

 public static void main(String[] argv) throws Exception {
   // Create a number spinner
   JSpinner spinner = new JSpinner();
   // Set its value
   spinner.setValue(new Integer(100));
 }

}


 </source>
   
  
 
  



Creating an Hour JSpinner Component

   <source lang="java">
 

import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.GregorianCalendar; import javax.swing.JFormattedTextField; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; import javax.swing.text.DateFormatter; import javax.swing.text.DefaultFormatterFactory; public class Main {

 public static void main(String[] argv) throws Exception {
   Calendar calendar = new GregorianCalendar();
   calendar.set(Calendar.HOUR_OF_DAY, 13); // 1pm
   SpinnerDateModel dateModel = new SpinnerDateModel(calendar.getTime(), null,
       null, Calendar.HOUR_OF_DAY);
   JSpinner spinner = new JSpinner(dateModel);
   JFormattedTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
   DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
   DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();
   // Change the date format to only show the hours
   formatter.setFormat(new SimpleDateFormat("hh:00 a"));
   //formatter.setFormat(new SimpleDateFormat("HH:00 a"));
 }

}


 </source>
   
  
 
  



Creating a SpinnerListModel That Loops Through Its Values

   <source lang="java">
 

import java.util.List; import javax.swing.JSpinner; import javax.swing.SpinnerListModel; public class Main {

 public static void main(String[] argv) throws Exception {
   SpinnerCircularListModel listModel = new SpinnerCircularListModel(
       new String[] { "red", "green", "blue" });
   JSpinner spinner = new JSpinner(listModel);
 }

} class SpinnerCircularListModel extends SpinnerListModel {

 public SpinnerCircularListModel(Object[] items) {
   super(items);
 }
 public Object getNextValue() {
   List list = getList();
   int index = list.indexOf(getValue());
   index = (index >= list.size() - 1) ? 0 : index + 1;
   return list.get(index);
 }
 public Object getPreviousValue() {
   List list = getList();
   int index = list.indexOf(getValue());
   index = (index <= 0) ? list.size() - 1 : index - 1;
   return list.get(index);
 }

}


 </source>
   
  
 
  



Customizing the Editor in a JSpinner Component: Create a color spinner

   <source lang="java">
 

import java.awt.Color; import java.awt.Dimension; import java.lang.reflect.Field; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerListModel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class Main {

 public static void main(String[] argv) throws Exception {
   ColorSpinner spinner = new ColorSpinner(new String[] { "red", "green","blue" });
  spinner.setValue("blue");
 }

} class ColorSpinner extends JSpinner {

 public ColorSpinner(String[] colorNames) {
   super();
   setModel(new SpinnerListModel(colorNames));
   setEditor(new Editor(this));
 }
 public class Editor extends JPanel implements ChangeListener {
   int preferredWidth = 30;
   int preferredHeight = 16;
   Editor(JSpinner spinner) {
     spinner.addChangeListener(this);
     setPreferredSize(new Dimension(preferredWidth, preferredHeight));
     setColor((String) spinner.getValue());
   }
   public void stateChanged(ChangeEvent evt) {
     JSpinner spinner = (JSpinner) evt.getSource();
     String value = (String) spinner.getValue();
     setColor(value);
   }
   public void setColor(String colorName) {
     try {
       Field field = Class.forName("java.awt.Color").getField(colorName);
       Color color = (Color) field.get(null);
       setBackground(color);
     } catch (Exception e) {
     }
   }
 }

}


 </source>
   
  
 
  



Date spinner

   <source lang="java">
 

import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; import javax.swing.SpinnerListModel; import javax.swing.SpinnerNumberModel; public class Main extends JFrame {

 public Main() {
   JSpinner m_dateSpinner;
   SpinnerDateModel m_dateSpinnerModel;
   Calendar rightNow = Calendar.getInstance();
   Date current = rightNow.getTime();
   rightNow.set(Calendar.HOUR_OF_DAY, -24);
   Date start = rightNow.getTime();
   rightNow.set(Calendar.HOUR_OF_DAY, 48);
   Date end = rightNow.getTime();
   int step = Calendar.HOUR_OF_DAY;
   m_dateSpinnerModel = new SpinnerDateModel(current, start, end, step);
   m_dateSpinner = new JSpinner(m_dateSpinnerModel);
   add(m_dateSpinner);
 }
 public static void main(String argv[]) {
   Main spinnerFrame = new Main();
   spinnerFrame.setSize(350, 200);
   spinnerFrame.setVisible(true);
 }

}


 </source>
   
  
 
  



Demonstrate the Swing Spinner control

   <source lang="java">
 

import java.awt.Container; import java.awt.GridLayout; import javax.swing.*; /**

* Demonstrate the Swing "Spinner" control.
* @author ian
*/

public class SpinnerDemo {

 public static void main(String[] args) {
   JFrame jf = new JFrame("It Spins");
   Container cp = jf.getContentPane();
   cp.setLayout(new GridLayout(0,1));
   // Create a JSpinner using one of the pre-defined SpinnerModels
   JSpinner dates = new JSpinner(new SpinnerDateModel());
   cp.add(dates);
   // Create a JSPinner using a SpinnerListModel. 
   String[] data = { "One", "Two", "Three" };
   JSpinner js = new JSpinner(new SpinnerListModel(data));
   cp.add(js);
   jf.setSize(100, 80);
   jf.setVisible(true);
 }

}



 </source>
   
  
 
  



Demonstrating the JSpinner Component

   <source lang="java">
 

import java.awt.BorderLayout; import java.awt.Container; import java.util.Calendar; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; import javax.swing.SpinnerListModel; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; public class SpinnerTest {

 public static void main(String args[]) {
   JFrame frame = new JFrame("Spinning");
   Container contentPane = frame.getContentPane();
   String months[] = { "January", "February", "March", "April", "May",
       "June", "July", "August", "September", "October", "November",
       "December" };
   SpinnerModel model = new SpinnerListModel(months);
   JSpinner spinner = new JSpinner(model);
   contentPane.add(spinner, BorderLayout.NORTH);
   SpinnerDateModel model2 = new SpinnerDateModel();
   model2.setCalendarField(Calendar.WEEK_OF_MONTH);
   JSpinner spinner2 = new JSpinner(model2);
   JSpinner.DateEditor editor2 = new JSpinner.DateEditor(spinner2,
       "MMMMM dd, yyyy");
   spinner2.setEditor(editor2);
   frame.getContentPane().add(spinner2, BorderLayout.CENTER);
   SpinnerNumberModel model3 = new SpinnerNumberModel(50, 0, 100, 5);
   JSpinner spinner3 = new JSpinner(model3);
   frame.getContentPane().add(spinner3, BorderLayout.SOUTH);
   frame.setSize(200, 100);
   frame.show();
 }

}


 </source>
   
  
 
  



Disabling Keyboard Editing in a JSpinner Component

   <source lang="java">
 

import java.awt.Color; import javax.swing.JFormattedTextField; import javax.swing.JSpinner; public class Main {

 public static void main(String[] argv) throws Exception {
   JSpinner spinner = new JSpinner();
   // Disable keyboard edits in the spinner
   JFormattedTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
   tf.setEditable(false);
   tf.setBackground(Color.white);
   // The value of the spinner can still be programmatically changed
   spinner.setValue(new Integer(100));
 }

}


 </source>
   
  
 
  



Enhanced Spinner List Formatter

   <source lang="java">
 

import java.text.ParseException; import java.util.Arrays; import java.util.List; import javax.swing.JFormattedTextField; import javax.swing.SpinnerListModel; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; /**

* Copyright 2007 Brandon Goodin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* ListFormatter provides completion while text is being input
* into the JFormattedTextField.rupletion is only done if the
* user is inserting text at the end of the document.rupletion
* is done by way of the SpinnerListModel method findNextMatch.
* This is largely a copy of the SpinnerListFormatter found in
* JDK 1.5 sources. A new version was written because the JDK
* version was not extensible and did not allow for the ability
* to ehance the stringToValue.
*
* The stringToValue was enhanced to iterate through the model
* list and compare the String values of the list objects and
* the string value passed to the formatter. The first equal
* will return. So, if multiple objects have the same toString
* value, only the first will be returned.
*/

public class EnhancedSpinnerListFormatter extends

   JFormattedTextField.AbstractFormatter {
 private DocumentFilter filter;
 private EnhancedSpinnerListModel model;
 public EnhancedSpinnerListFormatter(EnhancedSpinnerListModel model) {
   this.model = model;
 }
 public String valueToString(Object value) throws ParseException {
   if (value == null) {
     return "";
   }
   return value.toString();
 }
 public Object stringToValue(String string) throws ParseException {
   for (Object item : model.getList()) {
     if (item.toString().equals(string)) return item;
   }
   return null;
 }
 protected DocumentFilter getDocumentFilter() {
   if (filter == null) {
     filter = new Filter();
   }
   return filter;
 }
 private class Filter extends DocumentFilter {
   public void replace(FilterBypass fb, int offset, int length,
             String string, AttributeSet attrs) throws
       BadLocationException {
     if (string != null && (offset + length) ==
         fb.getDocument().getLength()) {
       Object next = model.findNextMatch(
           fb.getDocument().getText(0, offset) +
               string);
       String value = (next != null) ? next.toString() : null;
       if (value != null) {
         fb.remove(0, offset + length);
         fb.insertString(0, value, null);
         getFormattedTextField().select(offset +
             string.length(),
             value.length());
         return;
       }
     }
     super.replace(fb, offset, length, string, attrs);
   }
   public void insertString(FilterBypass fb, int offset,
                String string, AttributeSet attr)
       throws BadLocationException {
     replace(fb, offset, 0, string, attr);
   }
 }

}


/**

* Copyright 2007 Brandon Goodin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* This is a pretty much a direct copy of the SpinnerListModel from JDK 1.5 sources.
* It was copied out in order to expose methods that needed to be publicly available
* in order to allow for completion to work properly with a list of complex objects
* that present their human readable value from a toString(). The findNextMatch
* method was exposed as public.
*/

class EnhancedSpinnerListModel extends SpinnerListModel {

 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 IllegalArugmentException if values is
    *                                  null or zero size
    */
   @SuppressWarnings({"JavadocReference"})
   public EnhancedSpinnerListModel(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
    * IllegalArugmentException is thrown.
    *
    * @param values the sequence this model represents
    * @throws IllegalArugmentException if values is
    *                                  null or zero length
    */
   @SuppressWarnings({"JavadocReference"})
   public EnhancedSpinnerListModel(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 EnhancedSpinnerListModel() {
     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.
    * <p/>
    * 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 javax.swing.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 javax.swing.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 javax.swing.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 javax.swing.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
    */
   public 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;
   }

}


 </source>
   
  
 
  



Enhanced Spinner List Model

   <source lang="java">
 

import java.util.Arrays; import java.util.List; import javax.swing.SpinnerListModel;

/**

* Copyright 2007 Brandon Goodin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**

* This is a pretty much a direct copy of the SpinnerListModel from JDK 1.5 sources.
* It was copied out in order to expose methods that needed to be publicly available
* in order to allow for completion to work properly with a list of complex objects
* that present their human readable value from a toString(). The findNextMatch
* method was exposed as public.
*/

public class EnhancedSpinnerListModel extends SpinnerListModel {

 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 IllegalArugmentException if values is
    *                                  null or zero size
    */
   @SuppressWarnings({"JavadocReference"})
   public EnhancedSpinnerListModel(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
    * IllegalArugmentException is thrown.
    *
    * @param values the sequence this model represents
    * @throws IllegalArugmentException if values is
    *                                  null or zero length
    */
   @SuppressWarnings({"JavadocReference"})
   public EnhancedSpinnerListModel(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 EnhancedSpinnerListModel() {
     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.
    * <p/>
    * 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 javax.swing.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 javax.swing.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 javax.swing.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 javax.swing.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
    */
   public 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;
   }

}


 </source>
   
  
 
  



Java Spinner Component

Limiting the Values in a Number JSpinner Component

   <source lang="java">
 

import javax.swing.JSpinner; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel; public class Main {

 public static void main(String[] argv) throws Exception {
   // Create a number spinner that only handles values in the range [0,100]
   int min = 0;
   int max = 100;
   int step = 5;
   int initValue = 50;
   SpinnerModel model = new SpinnerNumberModel(initValue, min, max, step);
   JSpinner spinner = new JSpinner(model);
 }

}


 </source>
   
  
 
  



List based spinner

   <source lang="java">
 

import java.util.ArrayList; import java.util.List; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerListModel; public class Main extends JFrame {

 public Main() {
   JSpinner m_listSpinner;
   SpinnerListModel m_listSpinnerModel;
   List<String> sequence = new ArrayList<String>();
   sequence.add(new String("I - First"));
   sequence.add(new String("II - Second"));
   sequence.add(new String("III - Third"));
   sequence.add(new String("IV - Fourth"));
   sequence.add(new String("V - Fifth"));
   sequence.add(new String("VI - Sixth"));
   m_listSpinnerModel = new SpinnerListModel(sequence);
   m_listSpinner = new JSpinner(m_listSpinnerModel);
   add(m_listSpinner);
 }
 public static void main(String argv[]) {
   Main spinnerFrame = new Main();
   spinnerFrame.setSize(350, 200);
   spinnerFrame.setVisible(true);
 }

}


 </source>
   
  
 
  



Listening for Changes to the Value in a JSpinner Component

   <source lang="java">
 

import javax.swing.JSpinner; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class Main {

 public static void main(String[] argv) throws Exception {
   JSpinner spinner = new JSpinner();
   spinner.addChangeListener(new SpinnerListener());
   spinner.setValue(new Integer(100));
 }

} class SpinnerListener implements ChangeListener {

 public void stateChanged(ChangeEvent evt) {
   JSpinner spinner = (JSpinner) evt.getSource();
   // Get the new value
   Object value = spinner.getValue();
 }

}


 </source>
   
  
 
  



Number spinner

   <source lang="java">
 

import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import javax.swing.JFrame; import javax.swing.JSpinner; import javax.swing.SpinnerDateModel; import javax.swing.SpinnerListModel; import javax.swing.SpinnerNumberModel; public class Main extends JFrame {

 public Main() {
   JSpinner m_numberSpinner;
   SpinnerNumberModel m_numberSpinnerModel;
   Double current = new Double(5.50);
   Double min = new Double(0.00);
   Double max = new Double(10.00);
   Double step = new Double(0.25);
   m_numberSpinnerModel = new SpinnerNumberModel(current, min, max, step);
   m_numberSpinner = new JSpinner(m_numberSpinnerModel);
   add(m_numberSpinner);
 }
 public static void main(String argv[]) {
   Main spinnerFrame = new Main();
   spinnerFrame.setSize(350, 200);
   spinnerFrame.setVisible(true);
 }

}


 </source>
   
  
 
  



Setting the Margin Space on a JSpinner Component

   <source lang="java">
 

import java.awt.Insets; import javax.swing.JFormattedTextField; import javax.swing.JSpinner; public class Main {

 public static void main(String[] argv) throws Exception {
   JSpinner spinner = new JSpinner();
   // Get the text field
   JFormattedTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
   // Set the margin (add two spaces to the left and right side of the value)
   int top = 0;
   int left = 2;
   int bottom = 0;
   int right = 2;
   Insets insets = new Insets(top, left, bottom, right);
   tf.setMargin(insets);
 }

}


 </source>
   
  
 
  



Spinner 2

   <source lang="java">
 

/* Swing, Second Edition by Matthew Robinson, Pavel Vorobiev

  • /

import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.plaf.basic.BasicArrowButton; public class Spinner extends JPanel {

 private int m_orientation = SwingConstants.VERTICAL;
 private BasicArrowButton m_incrementButton;
 private BasicArrowButton m_decrementButton;
 public Spinner() {
   createComponents();
 }
 public Spinner(int orientation) {
   m_orientation = orientation;
   createComponents();
 }
 public void setEnabled(boolean enable) {
   m_incrementButton.setEnabled(enable);
   m_decrementButton.setEnabled(enable);
 }
 public boolean isEnabled() {
   return (m_incrementButton.isEnabled() && m_decrementButton.isEnabled());
 }
 protected void createComponents() {
   if (m_orientation == SwingConstants.VERTICAL) {
     setLayout(new GridLayout(2, 1));
     m_incrementButton = new BasicArrowButton(SwingConstants.NORTH);
     m_decrementButton = new BasicArrowButton(SwingConstants.SOUTH);
     add(m_incrementButton);
     add(m_decrementButton);
   } else if (m_orientation == SwingConstants.HORIZONTAL) {
     setLayout(new GridLayout(1, 2));
     m_incrementButton = new BasicArrowButton(SwingConstants.EAST);
     m_decrementButton = new BasicArrowButton(SwingConstants.WEST);
     add(m_decrementButton);
     add(m_incrementButton);
   }
 }
 public JButton getIncrementButton() {
   return (m_incrementButton);
 }
 public JButton getDecrementButton() {
   return (m_decrementButton);
 }
 public static void main(String[] args) {
   JFrame frame = new JFrame();
   JPanel panel = (JPanel) frame.getContentPane();
   panel.setLayout(new BorderLayout());
   JTextField field = new JTextField(20);
   Spinner spinner = new Spinner();
   panel.add(field, "Center");
   panel.add(spinner, "East");
   Dimension dim = frame.getToolkit().getScreenSize();
   frame.setLocation(dim.width / 2 - frame.getWidth() / 2, dim.height / 2
       - frame.getHeight() / 2);
   frame.pack();
   frame.show();
 }

}


 </source>
   
  
 
  



Use an Icon Editor for use with the JSpinner component

   <source lang="java">
 

import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JSpinner; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; class IconEditor extends JLabel implements ChangeListener {

 JSpinner spinner;
 Icon icon;
 public IconEditor(JSpinner s) {
   super((Icon)s.getValue(), CENTER);
   icon = (Icon)s.getValue();
   spinner = s;
   spinner.addChangeListener(this);
 }
 public void stateChanged(ChangeEvent ce) {
   icon = (Icon)spinner.getValue();
   setIcon(icon);
 }
 public JSpinner getSpinner() { return spinner; }
 public Icon getIcon() { return icon; }

}


 </source>
   
  
 
  



Use images in tooltips

   <source lang="java">
 

import javax.swing.JFrame; import javax.swing.JLabel; public class Main {

 public static void main(String[] args) {
   JFrame frame = new JFrame();
   JLabel label = new JLabel("Label with image in Tooltip!");
   label.setToolTipText("<html><img src=\"" + Main.class.getResource("tooltip.gif")
       + "\"> Tooltip ");
   label.setHorizontalAlignment(JLabel.CENTER);
   frame.setContentPane(label);
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   frame.setBounds(100, 100, 200, 100);
   frame.setVisible(true);
 }

}


 </source>