Java examples for Swing:JSpinner
Create and use Custom SpinnerNumberModel
/*// w ww.j a v a 2 s. co m * This application demonstrates using spinners. * Other files required: * SpringUtilities.java * CyclingSpinnerListModel.java */ import javax.swing.*; import java.awt.Color; import java.awt.Container; import java.util.Calendar; import java.util.Date; import javax.swing.SpinnerModel; import javax.swing.SpinnerListModel; /** * This 1.4 example is used by the various SpinnerDemos. * It implements a SpinnerListModel that works only with * an Object array and that implements cycling (the next * value and previous value are never null). It also * lets you optionally associate a spinner model that's * linked to this one, so that when a cycle occurs the * linked spinner model is updated. * The SpinnerDemos use the CyclingSpinnerListModel for * a month spinner that (in SpinnerDemo3) is tied to the * year spinner, so that -- for example -- when the month * changes from December to January, the year increases. */ class CyclingSpinnerListModel extends SpinnerListModel { Object firstValue, lastValue; SpinnerModel linkedModel = null; public CyclingSpinnerListModel(Object[] values) { super(values); firstValue = values[0]; lastValue = values[values.length - 1]; } public void setLinkedModel(SpinnerModel linkedModel) { this.linkedModel = linkedModel; } public Object getNextValue() { Object value = super.getNextValue(); if (value == null) { value = firstValue; if (linkedModel != null) { linkedModel.setValue(linkedModel.getNextValue()); } } return value; } public Object getPreviousValue() { Object value = super.getPreviousValue(); if (value == null) { value = lastValue; if (linkedModel != null) { linkedModel.setValue(linkedModel.getPreviousValue()); } } return value; } } public class SpinnerDemo extends JPanel { public SpinnerDemo(boolean cycleMonths) { super(new SpringLayout()); String[] labels = { "Month: ", "Year: ", "Another Date: " }; int numPairs = labels.length; Calendar calendar = Calendar.getInstance(); JFormattedTextField ftf = null; //Add the first label-spinner pair. String[] monthStrings = getMonthStrings(); //get month names SpinnerListModel monthModel = null; if (cycleMonths) { //use custom model monthModel = new CyclingSpinnerListModel(monthStrings); } else { //use standard model monthModel = new SpinnerListModel(monthStrings); } JSpinner spinner = addLabeledSpinner(this, labels[0], monthModel); //Tweak the spinner's formatted text field. ftf = getTextField(spinner); if (ftf != null) { ftf.setColumns(8); //specify more width than we need ftf.setHorizontalAlignment(JTextField.RIGHT); } //Add second label-spinner pair. int currentYear = calendar.get(Calendar.YEAR); SpinnerModel yearModel = new SpinnerNumberModel(currentYear, //initial value currentYear - 100, //min currentYear + 100, //max 1); //step //If we're cycling, hook this model up to the month model. if (monthModel instanceof CyclingSpinnerListModel) { ((CyclingSpinnerListModel) monthModel) .setLinkedModel(yearModel); } spinner = addLabeledSpinner(this, labels[1], yearModel); //Make the year be formatted without a thousands separator. spinner.setEditor(new JSpinner.NumberEditor(spinner, "#")); //Add the third label-spinner pair. Date initDate = calendar.getTime(); calendar.add(Calendar.YEAR, -100); Date earliestDate = calendar.getTime(); calendar.add(Calendar.YEAR, 200); Date latestDate = calendar.getTime(); SpinnerModel dateModel = new SpinnerDateModel(initDate, earliestDate, latestDate, Calendar.YEAR);//ignored for user input spinner = addLabeledSpinner(this, labels[2], dateModel); spinner.setEditor(new JSpinner.DateEditor(spinner, "MM/yyyy")); //Lay out the panel. // SpringUtilities.makeCompactGrid(this, numPairs, 2, //rows, cols // 10, 10, //initX, initY // 6, 10); //xPad, yPad } /** * Return the formatted text field used by the editor, or * null if the editor doesn't descend from JSpinner.DefaultEditor. */ public JFormattedTextField getTextField(JSpinner spinner) { JComponent editor = spinner.getEditor(); if (editor instanceof JSpinner.DefaultEditor) { return ((JSpinner.DefaultEditor) editor).getTextField(); } else { System.err.println("Unexpected editor type: " + spinner.getEditor().getClass() + " isn't a descendant of DefaultEditor"); return null; } } /** * DateFormatSymbols returns an extra, empty value at the * end of the array of months. Remove it. */ static protected String[] getMonthStrings() { String[] months = new java.text.DateFormatSymbols().getMonths(); int lastIndex = months.length - 1; if (months[lastIndex] == null || months[lastIndex].length() <= 0) { //last item empty String[] monthStrings = new String[lastIndex]; System.arraycopy(months, 0, monthStrings, 0, lastIndex); return monthStrings; } else { //last item not empty return months; } } static protected JSpinner addLabeledSpinner(Container c, String label, SpinnerModel model) { JLabel l = new JLabel(label); c.add(l); JSpinner spinner = new JSpinner(model); l.setLabelFor(spinner); c.add(spinner); return spinner; } /** * Create the GUI and show it. For thread safety, * this method should be invoked from the * event dispatch thread. */ private static void createAndShowGUI() { //Create and set up the window. JFrame frame = new JFrame("SpinnerDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Add content to the window. frame.add(new SpinnerDemo(false)); //Display the window. frame.pack(); frame.setVisible(true); } public static void main(String[] args) { //Schedule a job for the event dispatch thread: //creating and showing this application's GUI. SwingUtilities.invokeLater(new Runnable() { public void run() { //Turn off metal's use of bold fonts UIManager.put("swing.boldMetal", Boolean.FALSE); createAndShowGUI(); } }); } } /* * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle or the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */