JSpinner工作起來好像是在JList或者JComboBox中間放了一個JFormattedTextField
在JList或者JComboBox中
用戶可以提前設定好要輸入的值
JSpinner也提供這樣的一種機制
這個控件的另一個部分是JFormattedTextField
如何顯示和輸入不由那些小的控制格控制
比如JList
相反
可以通過JFormattedTextField來輸入或通過邊上的兩個小箭頭來浏覽不同的可用的值
圖示
顯示了Spinner伴隨不同的輸入類型是什麼樣子
圖示
的頂端的JSpinner是一個用來顯示法語星期
通過SpinnerListModel
中間的
是一個通過SpinnerDateModel顯示日期的JSpinner
底部的是使用SpinnerNumberModel的JSpinner
每一個都是通過各自神秘的方式
在本文的後面我們將要學習

圖示JSpinner實例 要創建和操縱JSpinner
許多類都將被調用
最重要的是JSpinner自己
最重要的兩個准素集包括SpinnerModel接口
包括可選擇的集合中的選項
還有
JSpinner
DefaultEditor的實現
用來捕獲所有選擇
慶幸的是
許多其它調用的類都是在後台工作的
比如
一旦你給SpinnerNumberModel提供了數字的范圍
並且用這個類來協助Spinner
你的工作實際上是完成了
創建JSpinner控件 JSpinner類包括兩個構造函數來初始化控件
public JSpinner()
JSpinner spinner = new JSpinner();
public JSpinner(SpinnerModel model)
SpinnerModel model = new SpinnerListModel(args);
JSpinner spinner = new JSpinner(model);
開始的時候可以沒有數據模型
後面可以使用它來跟蹤JSpinner的方法
另一個方法
在創建這個控件的時候使用完整的模型
實現SpinnerModel接口
它裡面有三個具體的子類可以使用
SpinnerDateModel
SpinnerListModel和SpinnerNumberModel
伴隨著他們的抽象父類AbstractSpinnerModel
如果不指名模型
那麼SpinnerNumberModel將默認使用
而顯示和編輯的控件是JFormattedTextField
編輯的基本功能是通過一系列JSpinner的內部類實現的
DateEditor
ListEditor和NumberFormat
還有父類中DefaultEditor的支持
JSpinner屬性 除了創建JSpinner對象之外
你還可以通過表一中的九個屬性中的一個來進行配置
Table JSpinner 屬性

value屬性中的值允許你更改當前控件的設置
nextValue和perviousValue可以使你以不同的方向察看模型中的入口
使用ChangeListener來監聽JSpinner events
JSpinner直接支持一種事件監聽
changeListener
在別的地方
當commitEdit()方法被調用
這個事件將被觸發
告訴你spinner的值發生改變
為了證明
列表
聯系到一個自定義的ChangeListener
與圖示
的程序相關聯
列表
JSpinner with ChangeListener
import java
awt
*;
import javax
swing
*;
import javax
swing
event
*;
import java
text
*;
import java
util
*;
public class SpinnerSample {
public static void main (String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame(
JSpinner Sample
);
frame
setDefaultCloseOperation(JFrame
EXIT_ON_CLOSE);
DateFormatSymbols symbols =
new DateFormatSymbols(Locale
FRENCH);
ChangeListener listener = new ChangeListener() {
public void stateChanged(ChangeEvent e) {
System
out
println(
Source:
+ e
getSource());
}
};
String days[] = symbols
getWeekdays();
SpinnerModel model
= new SpinnerListModel(days);
JSpinner spinner
= new JSpinner(model
);
spinner
addChangeListener(listener);
JLabel label
= new JLabel(
French Days/List
);
JPanel panel
= new JPanel(new BorderLayout());
panel
add(label
BorderLayout
WEST);
panel
add(spinner
BorderLayout
CENTER);
frame
add(panel
BorderLayout
NORTH);
SpinnerModel model
= new SpinnerDateModel();
JSpinner spinner
= new JSpinner(model
);
spinner
addChangeListener(listener);
JLabel label
= new JLabel(
Dates/Date
);
JPanel panel
= new JPanel(new BorderLayout());
panel
add(label
BorderLayout
WEST);
panel
add(spinner
BorderLayout
CENTER);
frame
add(panel
BorderLayout
CENTER);
SpinnerModel model
= new SpinnerNumberModel();
JSpinner spinner
= new JSpinner(model
);
spinner
addChangeListener(listener);
JLabel label
= new JLabel(
Numbers
);
JPanel panel
= new JPanel(new BorderLayout());
panel
add(label
BorderLayout
WEST);
panel
add(spinner
BorderLayout
CENTER);
frame
add(panel
BorderLayout
SOUTH);
frame
setSize(
);
frame
setVisible (true);
}
};
EventQueue
invokeLater(runner);
}
運行這個程序可以示范listener的用法(當然
你也會發現更多關於ChangeListener的有意義的方法)
定制JSpinner的外觀 同所有的Swing控件
JSpinner在不同的系統定義look
and
feel類型下
擁有不同的外觀
如示圖
這個控件期初看起來像一個textfield
不同點是繪制了兩個箭頭

示圖 JSpinner under different lookandfeel types
集合中的
個UIResource屬性在表格
中列舉
有限的方法繪制text field和箭頭
Table
JSpinner UIResource 元素
SpinnerModel 接口 到目前
我們已經看到了如何同一個主JSpinner類連接
SpinnerModel接口是控件的數據模型
SpinnerModel的定義如下
public interface SpinnerModel {
// Properties
public Object getValue();
public void setValue(Object);
public Object getNextValue();
public Object getPreviousValue();
// Listeners
public void addChangeListener(ChangeListener);
public void removeChangeListener(ChangeListener);
}
SpinnerModel中的六個方法直接繪制了JSpinner
而JSpinner的方法間接調用模塊中的方法
在監聽的狀況下
事件將聯系到監聽器
AbstractSpinnerModel類 AbstractSpinnerModel類基本要實現的是SpinnerModel接口
它提供了管理和通知的監聽列表
子類必須實現接口中的四個方法
SpinnerModel中的三個具體實現如下
SpinnerDateModel
SpinnerListModel和SpinnerNumberModel
SpinnerDateModel類 從名字可以推斷出
SpinnerDateModel提供了數據的選擇
這個類有兩個構造函數
一個默認選擇所有的數據
另一個要求你給出范圍
public SpinnerDateModel()SpinnerModel model = new SpinnerDateModel();JSpinner spinner = new JSpinner(model);public SpinnerDateModel(Date value
Comparable start
Comparable end
int calendarField)Calendar cal = Calendar
getInstance();Date now = cal
getTime();cal
add(Calendar
YEAR
);Date startDate = cal
getTime();cal
add(Calendar
YEAR
);Date endDate = cal
getTime();SpinnerModel model = new SpinnerDateModel(now
startDate
endDate
Calendar
YEAR);JSpinner spinner = new JSpinner(model);
如果不指名任何參數
就沒有開始和結束點
下面的例子展示了使用參數來表示
年的范圍
最後一個成員變量應該是Calendar類中的一個定值
· Calendar
AM_PM
· Calendar
DAY_OF_MONTH
· Calendar
DAY_OF_WEEK
· Calendar
DAY_OF_WEEK_IN_MONTH
· Calendar
DAY_OF_YEAR
· Calendar
ERA
· Calendar
HOUR
· Calendar
HOUR_OF_DAY
· Calendar
MILLISECOND
· Calendar
MINUTE
· Calendar
MONTH
· Calendar
SECOND
· Calendar
WEEK_OF_MONTH
· Calendar
WEEK_OF_YEAR
· Calendar
YEAR
注意
SpinnerDateModel不包含任何Calendar類中的時間域
所以不能通過SpinnerDateModel在JSpinner中翻轉
表格
列出了SpinnerModel中的三個屬性
四個關於SpinnerDateModel
Table SpinnerDateModel 屬性

典型地
唯一的新屬性中你將要用來獲得最終的日期
盡管所有的結果都被包裹在getValue()中
以適當的數據類型
如果在構造函數中提供了數據的表示范圍
那麼previous和next的值將是null
在邊界條件下
SpinnerListModel SpinnerListModel提供了從一個入口列表中選擇或者至少是字符串表述
這個類有三個構造函數
public SpinnerListModel()SpinnerModel model = new SpinnerListModel();
JSpinner spinner = new JSpinner(model);
public SpinnerListModel(List<?> values)List<String> list = args;
SpinnerModel model = new SpinnerListModel(list);
JSpinner spinner = new JSpinner(model);
public SpinnerListModel(Object[] values)SpinnerModel model = new SpinnerListModel(args);
JSpinner spinner = new JSpinner(model);
當沒有參數提供時
這個模型包括一個元素
字符串empty
List版保留一個對list的引用
而不是list的拷貝
如果改變了list
那麼模型中的list也將改變
數組版本的創建了一個私有的內部類
並且實例化一個list
對於list和數組版本
初始選擇的是第一個元素
否則將拋出一個IllegalArgumentException異常
如表格
顯示
屬性中增添的是set和get list
Table SpinnerListModel 屬性
educitycn/img_///gif > SpinnerNumberModel類 SpinnerNumberModel提供了從一個開區間或閉區間選擇數字的模式
數字可以使Number類的所有子類
包括Integer和Double
他有四個構造函數
public SpinnerNumberModel()SpinnerModel model = new SpinnerNumberModel();
JSpinner spinner = new JSpinner(model);
public SpinnerNumberModel(double value
double minimum
double maximum
double stepSize)SpinnerModel model = new SpinnerNumberModel(
);
JSpinner spinner = new JSpinner(model);
public SpinnerNumberModel(int value
int minimum
int maximum
int stepSize)SpinnerModel model = new SpinnerNumberModel(
);
JSpinner spinner = new JSpinner(model);
public SpinnerNumberModel(Number value
Comparable minimum
Comparable maximum
Number stepSize)Number value = new Integer(
);
Number min = new Integer(
);Number max = new Integer(
);
Number step = new Integer(
);SpinnerModel model = new SpinnerNumberModel(value
min
max
step);
JSpinner spinner = new JSpinner(model);
如果最大或最小值為null
則為開區間
對於沒有參數的
初始值為
步進為
步進是整形的
如果你設為
那麼將不會完成
表格
展示了SpinnerNumberModel的屬性
Table SpinnerNumberModel 屬性
educitycn/img_///gif > 自定義模型 一般來說
可用的JSpinner模型已經足夠了
所以沒有必要創建他的子類了
但是
並不是所有場合都能滿足
比如
你可能希望使用一個包裝了SpinnerListModel的模型
代替停止在第一個或最後一個元素
他包裝了另一個結束
在列表
中給出了具體實現
Listing
RolloverSpinnerListModel 類
import javax
swing
*;
import java
util
*;
public class RolloverSpinnerListModel extends SpinnerListModel {
public RolloverSpinnerListModel(List values) {
super(values);
}
public RolloverSpinnerListModel(Object[] values) {
super(values);
}
public Object getNextValue() {
Object returnValue = super
getNextValue();
if (returnValue == null) {
returnValue = getList()
get(
);
}
return returnValue;
}
public Object getPreviousValue() {
Object returnValue = super
getPreviousValue();
if (returnValue == null) {
List list = getList();
returnValue = list
get(list
size()
);
}
return returnValue;
}}
JSpinner編輯器 對於JSpinner每個可用的模型
一個次要的支持類
JSpinner的一個內部類
然而這個模塊可以控制控件是否可選
JSpinner編輯器允許你控制如何顯示和編輯每個可選的值
JSpinnerDefaultEditor類 JSpinner的setEditor()方法允許你將任何Jcomponent作為JSpinner的編輯器
當然你可以那樣做
更典型的是
你將用JSpinner
DefaultEditor的子類作運行
以JformattedTextField作為簡單的編輯器工作
將提供所有你需要的基本功能
它包括一個基本的構造函數
public JSpinner
DefaultEditor(JSpinner spinner)JSpinner spinner = new JSpinner();
JComponent editor = JSpinner
DefaultEditor(spinner);
spinner
setEditor(editor);
在表格
中可以看到
有兩個屬性
Table JSpinnerDefaultEditor properties
educitycn/img_///gif > 在不知道使用的是哪個模型工作的情況下
在這個級別的你可以做的是改變JformattedTextField中的文字顯示
更典型的是
你將改變模型編輯器的某些自定義方面
JSpinnerDateEditor類 DateEditor允許你定制不同的日期顯示方式
使用java
text包中SimpleDateFormat類
察看Javadoc了解更多的關於SimpleDateFormat的可用格式模式
如果你不喜歡默認的地顯示方式
可以通過給構造函數的第二個參數傳遞一個新參數來改變顯示模式
public JSpinner
DateEditor(JSpinner spinner)SpinnerModel model = new SpinnerDateModel();
JSpinner spinner = new JSpinner(model);JComponent editor = JSpinner
DateEditor(spinner);
spinner
setEditor(editor);
public JSpinner
DateEditor(JSpinner spinner
String dateFormatPattern)SpinnerModel model = new SpinnerDateModel();
JSpinner spinner = new JSpinner(model);
JComponent editor = JSpinner
DateEditor(spinner
MMMM yyyy
);
spinner
setEditor(editor);
默認情況
格式是M/d/yy h:mm a或者
/
/
:
PM 代表
年的聖誕節的某個時間
後面的例子將要顯示
December
編輯器的兩個屬性在表格
中
Table JSpinnerDateEditor屬性
educitycn/img_///gif > JSpinnerListEditor類 當使用SpinnerListModel類工作時
ListEditor不支持任何特殊格式
而是提供了前置類型支持
既然模塊的所有入口都知道了
編輯器將嘗試匹配用戶輸入的字符
這裡只有一個構造函數
但是你可能幾乎用不到
public JSpinner
ListEditor(JSpinner spinner)
在表格
中將看到ListEditor只有一個屬性
educitycn/img_///gif > JSpinnerNumberEditor類 NumberEditor和DateEditor的工作方式很相似
允許你輸入定制的顯示模式
代替SimpleDateFormat工作
NumberEditor可以協助java
text包中的DecimalFormat類
就像DateEditor一樣
他又兩個構造函數
public JSpinner
NumberEditor(JSpinner spinner)SpinnerModel model = new SpinnerNumberModel(
);JSpinner spinner = new JSpinner(model);JComponent editor = JSpinner
NumberEditor(spinner);spinner
setEditor(editor);public JSpinner
NumberEditor(JSpinner spinner
String decimalFormatPattern)SpinnerModel model = new SpinnerNumberModel(
);JSpinner spinner = new JSpinner(model);JComponent editor = JSpinner
NumberEditor(spinner
#
##
###
);spinner
setEditor(editor);
第二個構造函數使用默認的字符串格式
如果數字太大
將使用逗號
如果結果是一個完整的數
將不會用十進制顯示
表格
中
顯示editor的兩個屬性
Table JSpinnerNumberEditor 屬性
educitycn/img_///gif > 總結 在這篇文章中
你學習到了Swing中的JSpinner控件
當你要控制某些選擇在一定的范圍中時
JSpinner可以讓你通過翻滾來選擇需要的值
你學習到了如何提供這些要選擇的值
通過使用SpinnerDateModel和DateEditor
SpinnerListModel和ListEditor
SpinnerNumberModel和NumberEditor來設置日期
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26070.html