分享
 
 
 

Swing指南:Spinner Model Controls(组图)

王朝system·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

jspinner工作起来似乎是在JList或者JComboBox中间放了一个JFormattedTextField。在JList或者JComboBox中,用户可以提前设定好要输入的值。JSpinner也提供这样的一种机制。这个控件的另一个部分是JFormattedTextField。如何显示和输入不由那些小的控制格控制,比如JList。相反,可以通过JFormattedTextField来输入或通过边上的两个小箭头来浏览不同的可用的值。

图示1显示了Spinner伴随不同的输入类型是什么样子。图示1的顶端的JSpinner是一个用来显示法语星期,通过SpinnerListModel。中间的,是一个通过SpinnerDateModel显示日期的JSpinner。底部的是使用SpinnerNumberModel的JSpinner。每一个都是通过各自神秘的方式,在本文的后面我们将要学习。

图示1.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 1. JSpinner 属性

value属性中的值答应你更改当前控件的设置,nextValue和perviousValue可以使你以不同的方向察看模型中的入口。

使用ChangeListener来监听JSpinner events

JSpinner直接支持一种事件监听:changeListener。在别的地方,当commitEdit()方法被调用,这个事件将被触发,告诉你spinner的值发生改变。为了证实,列表1联系到一个自定义的ChangeListener,与图示1的程序相关联。

列表 1. 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 model1 = new SpinnerListModel(days);

JSpinner spinner1 = new JSpinner(model1);

spinner1.addChangeListener(listener);

JLabel label1 = new JLabel("French Days/List");

JPanel panel1 = new JPanel(new BorderLayout());

panel1.add(label1, BorderLayout.WEST);

panel1.add(spinner1, BorderLayout.CENTER);

frame.add(panel1, BorderLayout.NORTH);

SpinnerModel model2 = new SpinnerDateModel();

JSpinner spinner2 = new JSpinner(model2);

spinner2.addChangeListener(listener);

JLabel label2 = new JLabel("Dates/Date");

JPanel panel2 = new JPanel(new BorderLayout());

panel2.add(label2, BorderLayout.WEST);

panel2.add(spinner2, BorderLayout.CENTER);

frame.add(panel2, BorderLayout.CENTER);

SpinnerModel model3 = new SpinnerNumberModel();

JSpinner spinner3 = new JSpinner(model3);

spinner3.addChangeListener(listener);

JLabel label3 = new JLabel("Numbers");

JPanel panel3 = new JPanel(new BorderLayout());

panel3.add(label3, BorderLayout.WEST);

panel3.add(spinner3, BorderLayout.CENTER);

frame.add(panel3, BorderLayout.SOUTH);

frame.setSize(200, 90);

frame.setVisible (true);

}

};

EventQueue.invokeLater(runner);

}

运行这个程序可以示范listener的用法(当然,你也会发现更多关于ChangeListener的有意义的方法)。

定制JSpinner的外观

同所有的Swing控件,JSpinner在不同的系统定义look-and-feel类型下,拥有不同的外观,如示图2。这个控件期初看起来像一个textfield,不同点是绘制了两个箭头。

示图 2. JSpinner under different look-and-feel types

集合中的11个UIResource属性在表格2中列举,有限的方法绘制text field和箭头。

Table 2. 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, -50);Date startDate = cal.getTime();cal.add(Calendar.YEAR, 100);Date endDate = cal.getTime();SpinnerModel model = new SpinnerDateModel(now, startDate, endDate, Calendar.YEAR);JSpinner spinner = new JSpinner(model);

假如不指名任何参数,就没有开始和结束点。下面的例子展示了使用参数来表示100年的范围。最后一个成员变量应该是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中翻转。

表格3列出了SpinnerModel中的三个属性,四个关于SpinnerDateModel。

Table 3. 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异常。

如表格4显示,属性中增添的是set和get list。

Table 4. SpinnerListModel 属性

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(50, 0, 100, .25);

JSpinner spinner = new JSpinner(model);

public SpinnerNumberModel(int value, int minimum, int maximum, int stepSize)SpinnerModel model = new SpinnerNumberModel(50, 0, 100, 1);

JSpinner spinner = new JSpinner(model);

public SpinnerNumberModel(Number value, Comparable minimum, Comparable maximum,

Number stepSize)Number value = new Integer(50);

Number min = new Integer(0);Number max = new Integer(100);

Number step = new Integer(1);SpinnerModel model = new SpinnerNumberModel(value, min, max, step);

JSpinner spinner = new JSpinner(model);

假如最大或最小值为null,则为开区间。对于没有参数的,初始值为1,步进为1。步进是整形的,假如你设为.333,那么将不会完成。

表格5展示了SpinnerNumberModel的属性:

Table 5. SpinnerNumberModel 属性

自定义模型

一般来说,可用的JSpinner模型已经足够了,所以没有必要创建他的子类了。但是,并不是所有场合都能满足。比如,你可能希望使用一个包装了SpinnerListModel的模型,代替停止在第一个或最后一个元素,他包装了另一个结束。在列表2中给出了具体实现:

Listing 2. 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(0);

}

return returnValue;

}

public Object getPreviousValue() {

Object returnValue = super.getPreviousValue();

if (returnValue == null) {

List list = getList();

returnValue = list.get(list.size() - 1);

}

return returnValue;

}}

JSpinner编辑器

对于JSpinner每个可用的模型,一个次要的支持类,JSpinner的一个内部类。然而这个模块可以控制控件是否可选,JSpinner编辑器答应你控制如何显示和编辑每个可选的值。

JSpinner.DefaultEditor类

JSpinner的setEditor()方法答应你将任何Jcomponent作为JSpinner的编辑器,当然你可以那样做,更典型的是,你将用JSpinner.DefaultEditor的子类作运行。以JformattedTextField作为简单的编辑器工作,将提供所有你需要的基本功能。它包括一个基本的构造函数:

public JSpinner.DefaultEditor(JSpinner spinner)JSpinner spinner = new JSpinner();

JComponent editor = JSpinner.DefaultEditor(spinner);

spinner.setEditor(editor);

在表格6中可以看到,有两个属性:

Table 6. JSpinner.DefaultEditor properties

在不知道使用的是哪个模型工作的情况下,在这个级别的你可以做的是改变JformattedTextField中的文字显示。更典型的是,你将改变模型编辑器的某些自定义方面。

JSpinner.DateEditor类

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或者12/25/04 12:34 PM 代表2004年的圣诞节的某个时间。后面的例子将要显示2004 December。

编辑器的两个属性在表格7中。

Table 7. JSpinner.DateEditor属性

JSpinner.ListEditor类

当使用SpinnerListModel类工作时,ListEditor不支持任何非凡格式。而是提供了前置类型支持。既然模块的所有入口都知道了,编辑器将尝试匹配用户输入的字符。这里只有一个构造函数,但是你可能几乎用不到。

public JSpinner.ListEditor(JSpinner spinner)

在表格8中将看到ListEditor只有一个属性:

JSpinner.NumberEditor类

NumberEditor和DateEditor的工作方式很相似,答应你输入定制的显示模式。代替SimpleDateFormat工作,NumberEditor可以协助java.text包中的DecimalFormat类。就像DateEditor一样,他又两个构造函数:

public JSpinner.NumberEditor(JSpinner spinner)SpinnerModel model = new SpinnerNumberModel(50, 0, 100, .25);JSpinner spinner = new JSpinner(model);JComponent editor = JSpinner.NumberEditor(spinner);spinner.setEditor(editor);public JSpinner.NumberEditor(JSpinner spinner, String decimalFormatPattern)SpinnerModel model = new SpinnerNumberModel(50, 0, 100, .25);JSpinner spinner = new JSpinner(model);JComponent editor = JSpinner.NumberEditor(spinner, "#,##0.###");spinner.setEditor(editor);

第二个构造函数使用默认的字符串格式。假如数字太大,将使用逗号。假如结果是一个完整的数,将不会用十进制显示。

表格9中,显示editor的两个属性。

Table 9. JSpinner.NumberEditor 属性

总结

在这篇文章中,你学习到了Swing中的JSpinner控件。当你要控制某些选择在一定的范围中时,JSpinner可以让你通过翻滚来选择需要的值。你学习到了如何提供这些要选择的值:通过使用SpinnerDateModel和DateEditor,SpinnerListModel和ListEditor,SpinnerNumberModel和NumberEditor来设置日期。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有