允許用戶從帶有 JSpinner
的拾取列表中快速選擇日期、數字和選項
John Zukowski (jaz@zukowski.net)
總裁,JZ Ventures, Inc.
2001 年 7 月
歡迎閱讀 Merlin 的魔力,一個半月刊的短篇系列,目的是為使用 Java 2 標準版,版本 1.4 編程提供幫助。在隨后的幾個月中,作者 John Zukowski 將提供一些技巧和訣竅來利用此發行版中許多新功能。在這個部分中,John 描述了 Swing 的新 JSpinner
組件,它允許您從拾取列表中選擇日期、數字和選項。請點擊文章頂部或底部的 討論,參與討論論壇,與本文作者和其他讀者分享您對本文的看法。
Java 2 SDK,1.4 beta 的最新發行版向 JFC/Swing 組件集添加了兩個強大的新組件。其中一個是 JSpinner
,它使用戶能夠方便地選擇日期、數字或拾取列表中的選項。(另一個是 JFormattedTextField
,用于支持格式化的輸入。)
開始啟動
JSpinner
使您可創建一個排序的值列表,該表在選擇框中每次顯示一個選項,如圖 1 所示。用戶通過點擊上移和下移箭頭進行選擇。
圖 1. JSpinner 示例

用戶使用組件或鍵盤上的上移和下移箭頭進行選擇。他們也可輸入自己的選擇。然而,與 JComboBox
不同,JSpinner
不提供下拉列表選擇,所以各個選擇以及它們的順序應有一定的意義。
要使用類,可簡單地創建一個供選擇的元素集合(在 List
或數組中),從列表中創建一個 SpinnerModel
,并為模型創建一個 JSpinner
:
清單 1. 簡單的 JSpinner 用法
String[] months = new DateFormatSymbols().getMonths();
SpinnerModel model = new SpinnerListModel(months);
JSpinner spinner = new JSpinner(model);
|
根據您所用的輸入類型,有以下幾個可用于創建組件數據模型的幫助類:
SpinnerDateModel
:用于接受日期輸入。該類支持通過將 Calendar
類中的常數設置為不同的值來更改日期;例如,Calendar.WEEK_OF_MONTH
每次將日期更改一周。
SpinnerListModel
:用于接受來自值列表的輸入。
SpinnerNumberModel
:用于接受已設定好步長的一定范圍內的數字( int
或 double
)的輸入。
每個 SpinnerModel
執行取決于用于輸入值的編輯器。此編輯器必須是一個 JComponent
;系統定義的編輯器子類 JSpinner.DefaultEditor
。其中一個可用于每個模型:
JSpinner.DateEditor
:用于 SpinnerDateModel
。允許您定制輸入日期格式。
JSpinner.ListEditor
:用于 SpinnerListModel
。支持 type-ahead 來對值進行定位。
JSpinner.NumberEditor
:用于 SpinnerNumberModel
。允許您定制十進制格式的模式。
所有這些類(及更多類)之間的關系如圖 2 所示。
圖 2. JSpinner UML 關系示意圖

事件處理
JSpinner
組件象其它 Swing 組件一樣工作。如果您有興趣查出用戶更改選擇的時間,請連一個偵聽器。對于 JSpinner
,偵聽器是一個 ChangeListener
,您可直接將其連到 JSpinner
或其 SpinnerModel
上。雖然您可將偵聽器連到兩者中的任意一個,當值發生更改時,ChangeEvent
的源總是 SpinnerModel
:
清單 2. JSpinner 事件偵聽
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
SpinnerModel source = (SpinnerModel)e.getSource();
System.out.println("The value is: " + source.getValue());
}
};
model.addChangeListener(listener);
|
一個完整的示例
讓我們來看一下使用全部三種不同的 spinner 模型的示例(清單 3)。列表模型使用從 DateFormatSymbols
類取出的月份名稱集。日期模型示例更改編輯器的輸入格式。(beta 發行版中好象存在一處錯誤,當編輯器更改時不重新格式化字段。)當使用該字段旁邊的箭頭時,每次也可將日期移動一周。數字模型示例讓用戶選取從 0 到 100 之間的一個數字,當使用箭頭時每次跳 5 個數。請注意:用戶可輸入任意數字,而并不僅限于 5 的倍數。
對于所有組件來說,當每個 spinner 值確實發生更改時,所連的偵聽器將顯示同一改變。如果使用光標鍵更改月、日或年,您會注意到直到按下回車鍵這些值才發生更改。
清單 3. JSpinner 完整示例
import javax.swing.*;
import javax.swing.event.*;
import java.text.*;
import java.awt.*;
import java.util.*;
public class Spinner {
public static void main (String args[]) throws Exception {
JFrame frame = new JFrame("Spinner");
frame.setDefaultCloseOperation(3);
String[] months = new DateFormatSymbols().getMonths();
SpinnerModel model = new SpinnerListModel(months);
JSpinner spinner = new JSpinner(model);
frame.getContentPane().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.SOUTH);
SpinnerNumberModel model3 = new SpinnerNumberModel(50, 0, 100, 5);
JSpinner spinner3 = new JSpinner(model3);
frame.getContentPane().add(spinner3, BorderLayout.CENTER);
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
SpinnerModel source = (SpinnerModel)e.getSource();
System.out.println("The value is: " + source.getValue());
}
};
model.addChangeListener(listener);
model2.addChangeListener(listener);
model3.addChangeListener(listener);
frame.pack();
frame.show();
}
}
|
參考資料
posted on 2005-02-05 20:25
jacky 閱讀(463)
評論(0) 編輯 收藏