The Java Tutorials have been written for JDK 8.Java教程是为JDK 8编写的。Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available.本页中描述的示例和实践没有利用后续版本中引入的改进,并且可能使用不再可用的技术。See Java Language Changes for a summary of updated language features in Java SE 9 and subsequent releases.有关Java SE 9及其后续版本中更新的语言特性的摘要,请参阅Java语言更改。
See JDK Release Notes for information about new features, enhancements, and removed or deprecated options for all JDK releases.有关所有JDK版本的新功能、增强功能以及已删除或不推荐的选项的信息,请参阅JDK发行说明。
Spinners are similar to combo boxes and lists in that they let the user choose from a range of values. 微调器类似于组合框和列表,因为它们允许用户从一系列值中进行选择。Like editable combo boxes, spinners allow the user to type in a value. 与可编辑组合框一样,微调器允许用户输入值。Unlike combo boxes, spinners do not have a drop-down list that can cover up other components. 与组合框不同,微调器没有可以覆盖其他组件的下拉列表。Because spinners do not display possible values only the current value is visible they are often used instead of combo boxes or lists when the set of possible values is extremely large. 因为微调器不显示可能的值;只有当前值可见;当可能的值集非常大时,通常使用它们来代替组合框或列表。However, spinners should only be used when the possible values and their sequence are obvious.但是,仅当可能的值及其顺序明显时才应使用微调器。
A spinner is a compound component with three subcomponents: two small buttons and an editor. 微调器是一个包含三个子组件的复合组件:两个小按钮和一个编辑器。The editor can be any 编辑器可以是任何JComponent, but by default it is implemented as a panel that contains a formatted text field. JComponent,但默认情况下,它实现为包含格式化文本字段的面板。The spinner's possible and current values are managed by its model.微调器的可能值和当前值由其模型管理。
Here is a picture of an application named 下面是名为SpinnerDemo that has three spinners used to specify dates:SpinnerDemo的应用程序的图片,该应用程序有三个用于指定日期的微调器:

The code for the main class can be found in 主类的代码可以在SpinnerDemo.java. SpinnerDemo.java中找到。The Month spinner displays the name of the first month in the user's locale. “月份”微调器显示用户区域设置中第一个月的名称。The possible values for this spinner are specified using an array of strings. 使用字符串数组指定此微调器的可能值。The Year spinner displays one value of a range of integers, initialized to the current year. “年份”微调器显示一系列整数中的一个值,初始化为当前年份。The Another Date spinner displays one value in a range of 另一个日期微调器以自定义格式显示一系列Date objects (initially the current date) in a custom format that shows just a month and year.Date对象(最初为当前日期)中的一个值,仅显示月份和年份。

To create a spinner, first create its model and then pass the model into the JSpinner constructor. 要创建微调器,首先创建其模型,然后将模型传递到JSpinner构造函数。For example:例如:
String[] monthStrings = getMonthStrings(); //get month names SpinnerListModel monthModel = new SpinnerListModel(monthStrings); JSpinner spinner = new JSpinner(monthModel);
The rest of this section covers the following topics:本节其余部分包括以下主题:
The Swing API provides three spinner models:Swing API提供了三种微调器模型:
SpinnerListModel is a model whose values are defined by an array of objects or a List object. SpinnerListModel是一个模型,其值由对象数组或List对象定义。SpinnerDemo example uses this model, initialized with an array derived from the value returned by the getMonths method of the java.text.DateFormatSymbols class. SpinnerDemo示例中的月份微调器使用此模型,初始化时使用从java.text.DateFormatSymbols类的getMonths方法返回的值派生的数组。SpinnerDemo.java for details.SpinnerDemo.java。SpinnerNumberModel supports sequences of numbers which can be expressed as double objects, int objects, or Number objects. SpinnerNumberModel支持可以表示为double对象、int对象或Number对象的数字序列。SpinnerModel model =
new SpinnerNumberModel(currentYear, //initial value
currentYear - 100, //min
currentYear + 100, //max
1); //stepSpinnerDateModel supports sequences of Date objects. SpinnerDateModel支持Date对象序列。Calendar.YEAR) to increment or decrement. Calendar.YEAR)。Date initDate = calendar.getTime();
calendar.add(Calendar.YEAR, -100);
Date earliestDate = calendar.getTime();
calendar.add(Calendar.YEAR, 200);
Date latestDate = calendar.getTime();
model = new SpinnerDateModel(initDate,
earliestDate,
latestDate,
Calendar.YEAR);When you set the spinner's model, the spinner's editor is automatically set. 设置微调器的模型时,会自动设置微调器编辑器。The Swing API provides an editor class corresponding to each of the three model classes listed above. Swing API提供了一个编辑器类,它对应于上面列出的三个模型类中的每一个。These classes JSpinner.ListEditor, JSpinner.NumberEditor, and JSpinner.DateEditor are all subclasses of the JSpinner.DefaultEditor class that feature editable formatted text fields. 这些类别JSpinner.ListEditor、JSpinner.NumberEditor和JSpinner.DateEditor是JSpinner.DefaultEditor类的所有子类,具有可编辑的格式化文本字段。If you use a model that does not have an editor associated with it, the editor is by default a 如果您使用的模型没有与其关联的编辑器,则默认情况下,该编辑器是带有不可编辑格式文本字段的JSpinner.DefaultEditor instance with a non-editable formatted text field.JSpinner.DefaultEditor实例。
To change the formatting used in a standard spinner editor, you can create and set the editor yourself.要更改标准微调器编辑器中使用的格式,可以自己创建和设置编辑器。
The JSpinner.NumberEditor and JSpinner.DateEditor classes have constructors that allow you to create an editor that formats its data in a particular way. JSpinner.NumberEditor和JSpinner.DateEditor类具有构造函数,允许您创建以特定方式格式化其数据的编辑器。For example, the following code sets up the Another Date spinner so that instead of using the default date format, which is long and includes the time, it shows just a month and year in a compact way.例如,下面的代码设置了另一个日期微调器,因此,它不使用默认的日期格式(长且包含时间),而是以紧凑的方式显示月份和年份。
spinner.setEditor(new JSpinner.DateEditor(spinner, "MM/yyyy"));
You can play with date formats by running 您可以通过运行ComboBoxDemo2 example. ComboBoxDemo2示例来使用日期格式。Click the Launch button to run ComboBoxDemo2 using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行ComboBoxDemo2(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引。

For information about format strings, see the Formatting lesson of the Internationalization trail.有关格式化字符串的信息,请参阅国际化教程的格式化课程。
To change the formatting when using a default editor, you can obtain the editor's formatted text field and invoke methods on it. 要在使用默认编辑器时更改格式,可以获取编辑器的格式化文本字段并调用其上的方法。You can call those methods using the 可以使用getTextField method defined in the JSpinner.DefaultEditor class. JSpinner.DefaultEditor类中定义的getTextField方法调用这些方法。Note that the Swing-provided editors are not formatted text fields. 注意,Swing提供的编辑器不是格式化的文本字段。Instead, they are the 相反,它们是包含格式化文本字段的JPanel instances that contain a formatted text field. JPanel实例。Here is an example of getting and invoking methods on the editor's formatted text field:下面是在编辑器的格式化文本字段上获取和调用方法的示例:
//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);
}
...
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;
}
}If the existing spinner models or editors do not meet your needs, you can create your own.如果现有微调器模型或编辑器不满足您的需要,您可以创建自己的微调器模型。
The easiest route to creating a custom spinner model is to create a subclass of an existing 创建自定义微调器模型的最简单方法是创建现有AbstractSpinnerModel subclass that already does most of what you need. AbstractSpinnerModel子类的子类,该子类已经完成了您所需的大部分工作。An alternative is to implement your own class by extending 另一种方法是通过扩展AbstractSpinnerModel class, which implements the event notifications required for all spinner models.AbstractSpinnerModel类来实现自己的类,该类实现所有微调器模型所需的事件通知。
The following subclass of SpinnerListModel implements a spinner model that cycles through an array of objects. SpinnerListModel的以下子类实现了一个在对象数组中循环的微调器模型。It also lets you specify a second spinner model that will be updated whenever the cycle begins again. 它还允许您指定第二个微调器模型,该模型将在循环再次开始时更新。For example, if the array of objects is a list of months, the linked model could be for a spinner that displays the year. 例如,如果对象数组是月份列表,则链接模型可以用于显示年份的微调器。When the month flips over from December to January the year is incremented. 当月份从12月翻转到1月时,年递增。Similarly, when the month flips back from January to December the year is decremented.类似地,当月份从1月倒转到12月时,年份将递减。
public 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;
}
}The CyclingSpinnerListModel model is used for the Month spinner in the SpinnerDemo2 example, an example that is almost identical to the SpinnerDemo. CyclingSpinerListModel模型用于SpinerDemo2示例中的月份微调器,该示例与Spinerdemo几乎相同。Click the Launch button to run SpinnerDemo2 using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行SpinnerDemo2(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引。

As we mentioned before, if you implement a spinner model that does not descend from 如前所述,如果实现的微调器模型不从SpinnerListModel, SpinnerNumberModel, or SpinnerDateModel, then the spinner's default editor is a non-editable instance of JSpinner.DefaultEditor. SpinnerListModel、SpinnerNumberModel或SpinnedDateModel派生,则微调器的默认编辑器是JSpinner.DefaultEditor的不可编辑实例。As you have already seen, you can set a spinner's editor by invoking the 正如您已经看到的,可以在设置微调器的模型属性后,通过调用微调器上的setEditor method on the spinner after the spinner's model property has been set. setEditor方法来设置微调器编辑器。An alternative to using 使用setEditor is to create a subclass of the JSpinner class and override its createEditor method so that it returns a particular kind of editor whenever the spinner model is of a certain type.setEditor的另一种方法是创建JSpinner类的子类并重写其createEditor方法,以便每当微调器模型具有特定类型时,它都返回特定类型的编辑器。
In theory at least, you can use any 至少在理论上,您可以使用任何JComponent instance as an editor. JComponent实例作为编辑器。Possibilities include using a subclass of a standard component such as 可能包括使用标准组件的子类,如JLabel, or a component you have implemented from scratch, or a subclass of JSpinner.DefaultEditor. JLabel,或者从头实现的组件,或者JSpinner.DefaultEditor的子类。The only requirements are that the editor must be updated to reflect changes in the spinner's value, and it must have a reasonable preferred size. 唯一的要求是编辑器必须更新以反映微调器值的变化,并且必须具有合理的首选大小。The editor should generally also set its tool tip text to whatever tool tip text has been specified for the spinner. 编辑器通常还应将其工具提示文本设置为已为微调器指定的任何工具提示文本。An example of implementing an editor is provided in the next section.下一节将提供实现编辑器的示例。
You can detect that a spinner's value has changed by registering a change listener on either the spinner or its model. 通过在微调器或其模型上注册更改侦听器,可以检测微调器的值已更改。Here is an example of implementing such a change listener. 下面是实现这种更改侦听器的示例。This example is from 此示例来自SpinnerDemo3, which is based on SpinnerDemo and uses a change listener to change the color of some text to match the value of the Another Date spinner. SpinnerDemo3,它基于SpinnedDemo,并使用更改侦听器更改某些文本的颜色以匹配另一个日期微调器的值。Click the Launch button to run SpinnerDemo3 using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行SpinnerDemo3(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引。

public class SpinnerDemo3 extends JPanel
implements ChangeListener {
protected Calendar calendar;
protected JSpinner dateSpinner;
...
public SpinnerDemo3() {
...
SpinnerDateModel dateModel = ...;
...
setSeasonalColor(dateModel.getDate()); //initialize color
//Listen for changes on the date spinner.
dateSpinner.addChangeListener(this);
...
}
public void stateChanged(ChangeEvent e) {
SpinnerModel dateModel = dateSpinner.getModel();
if (dateModel instanceof SpinnerDateModel) {
setSeasonalColor(((SpinnerDateModel)dateModel).getDate());
}
}
protected void setSeasonalColor(Date date) {
calendar.setTime(date);
int month = calendar.get(Calendar.MONTH);
JFormattedTextField ftf = getTextField(dateSpinner);
if (ftf == null) return;
//Set the color to match northern hemisphere seasonal conventions.
switch (month) {
case 2: //March
case 3: //April
case 4: //May
ftf.setForeground(SPRING_COLOR);
break;
...
default: //December, January, February
ftf.setForeground(WINTER_COLOR);
}
}
...
}The following example implements an editor which has a change listener so that it can reflect the spinner's current value. 以下示例实现了一个编辑器,该编辑器具有一个更改侦听器,以便它可以反映微调器的当前值。This particular editor displays a solid color of gray, ranging anywhere from white to black. 此特定编辑器显示灰色的纯色,范围从白色到黑色。Click the Launch button to run SpinnerDemo4 using Java™ Web Start (download JDK 7 or later). 单击启动按钮,使用Java™Web启动运行SpinnerDemo4(下载JDK 7或更高版本)。Alternatively, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引。

...//Where the components are created:
JSpinner spinner = new JSpinner(new GrayModel(170));
spinner.setEditor(new GrayEditor(spinner));
class GrayModel extends SpinnerNumberModel {
...
}
class GrayEditor extends JLabel
implements ChangeListener {
public GrayEditor(JSpinner spinner) {
setOpaque(true);
...
//Get info from the model.
GrayModel myModel = (GrayModel)(spinner.getModel());
setBackground(myModel.getColor());
spinner.addChangeListener(this);
...
updateToolTipText(spinner);
}
protected void updateToolTipText(JSpinner spinner) {
String toolTipText = spinner.getToolTipText();
if (toolTipText != null) {
//JSpinner has tool tip text. Use it.
if (!toolTipText.equals(getToolTipText())) {
setToolTipText(toolTipText);
}
} else {
//Define our own tool tip text.
GrayModel myModel = (GrayModel)(spinner.getModel());
int rgb = myModel.getIntValue();
setToolTipText("(" + rgb + "," + rgb + "," + rgb + ")");
}
}
public void stateChanged(ChangeEvent e) {
JSpinner mySpinner = (JSpinner)(e.getSource());
GrayModel myModel = (GrayModel)(mySpinner.getModel());
setBackground(myModel.getColor());
updateToolTipText(mySpinner);
}
}The following tables list some of the commonly used API for using spinners. 下表列出了使用微调器的一些常用API。If you need to deal directly with the editor's formatted text field, you should also see The FormattedTextField API. 如果需要直接处理编辑器的格式化文本字段,还应该看到FormattedTextField API。Other methods you might use are listed in the API tables in The JComponent Class.您可能使用的其他方法在JComponent类的API表中列出。
SpinnerListModelSpinnerDateModelSpinnerNumberModelJSpinner |
|
SpinnerModel |
|
AbstractSpinnerModel |
|
SpinnerListModel |
AbstractSpinnerModel whose values are defined by an array or a List.AbstractSpinnerModel的一个子类,其值由数组或List定义。 |
SpinnerDateModel |
AbstractSpinnerModel that supports sequences of Date instances.AbstractSpinnerModel的一个子类,支持Date实例序列。 |
SpinnerNumberModel |
AbstractSpinnerModel that supports sequences of numbers.AbstractSpinnerModel的一个子类,支持数字序列。 |
JSpinner.DefaultEditor |
|
JSpinner.ListEditor |
JSpinner.DefaultEditor whose values are defined by an array or a List.JSpinner.DefaultEditor的一个子类,其值由数组或List定义。 |
JSpinner.DateEditor |
JSpinner.DefaultEditor that supports sequences of Date instances.JSpinner.DefaultEditor的一个子类,支持Date实例序列。 |
JSpinner.NumberEditor |
JSpinner.DefaultEditor that supports sequences of numbers.JSpinner.DefaultEditor的一个子类,支持数字序列。 |
JSpinner()JSpinner(SpinnerModel) |
JSpinner. JSpinner。SpinnerNumberModel with an initial value of 0 and no minimum or maximum limits. SpinnerNumberModel创建微调器。SpinnerModel.SpinnerModel。 |
void setValue(java.lang.Object)Object getValue() |
|
Object getNextValue()Object getPreviousValue() |
getValue method.getValue方法返回的对象之前或之后的对象。 |
SpinnerModel getModel()void setModel(SpinnerModel) |
|
JComponent getEditor()void setEditor(JComponent) |
JSpinner.DefaultEditor.JSpinner.DefaultEditor类型的对象。 |
protected JComponent createEditor(SpinnerModel) |
JSpinner constructors to create the spinner's editor. JSpinner构造函数调用以创建微调器的编辑器。 |
JSpinner.NumberEditor(JSpinner, String) |
JSpinner.NumberEditor instance that displays and allows editing of the number value of the specified spinner. JSpinner.NumberEditor实例,该实例显示并允许编辑指定微调器的数值。 |
JSpinner.DateEditor(JSpinner, String) |
JSpinner.DateEditor instance that displays and allows editing of the Date value of the specified spinner. JSpinner.DateEditor实例,该实例显示并允许编辑指定微调器的Date值。 |
JFormattedTextField getTextField()( JSpinner.DefaultEditorJSpinner.DefaultEditor中定义) |
void setList(List)List getList() |
List that defines the sequence for this model.List。 |
void setValue(Object)Date getDate()Object getValue() |
Date for this sequence.Date。 |
void setStart(Comparable)Comparable getStart() |
Date in this sequence. Date。null to specify that the spinner has no lower limit.null指定微调器没有下限。 |
void setEnd(Comparable)Comparable getEnd() |
Date in this sequence. Date。null to specify that the spinner has no upper limit.null指定微调器没有上限。 |
void setCalendarField(int)int getCalendarField() |
getNextValue and getPreviousValue methods. getNextValue和getPreviousValue方法使用的日期值增量的大小。Calendar: ERA, YEAR, MONTH, WEEK_OF_YEAR, WEEK_OF_MONTH, DAY_OF_MONTH, DAY_OF_YEAR, DAY_OF_WEEK, DAY_OF_WEEK_IN_MONTH, AM_PM, HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND.Calendar中定义的下列常量之一:ERA、YEAR、MONTH、WEEK_OF_YEAR、WEEK_OF_MONTH、DAY_OF_MONTH、DAY_OF_YEAR、DAY_OF_WEEK、DAY_OF_WEEK_IN_MONTH、AM_PM、HOUR_OF_DAY、MINUTE、SECOND、MILLISECOND |
void setValue(Object)Number getNumber() |
|
void setMaximum(Comparable)Comparable getMaximum() |
null, there is no upper bound.null,则没有上限。 |
void setMinimum(Comparable)Comparable getMinimum() |
null, there is no lower bound.null,则没有下限。 |
void setStepSize(Number)Number getStepSize() |
getNextValue and getPreviousValue methods.getNextValue和getPreviousValue方法使用的增量。 |
This table lists examples that use spinners and points to where those examples are described.下表列出了使用微调器的示例,并指出了这些示例的描述位置。
SpinnerDemo |
||
SpinnerDemo2 |
SpinnerDemo subclass that uses the custom spinner model for its Months spinner.SpinnerDemo子类,使用自定义微调器模型作为其月份微调器。 | |
SpinnerDemo3 |
SpinnerDemo,该应用程序演示了如何监听微调器值的变化。 | |
SpinnerDemo4 |