服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

swing指南:spinner model controls(组图)


  jspinner工作起来好像是在jlist或者jcombobox中间放了一个jformattedtextfield。在jlist或者jcombobox中,用户可以提前设定好要输入的值。jspinner也提供这样的一种机制。这个控件的另一个部分是jformattedtextfield。如何显示和输入不由那些小的控制格控制,比如jlist。相反,可以通过jformattedtextfield来输入或通过边上的两个小箭头来浏览不同的可用的值。
  
  图示1显示了spinner伴随不同的输入类型是什么样子。图示1的顶端的jspinner是一个用来显示法语星期,通过spinnerlistmodel。中间的,是一个通过spinnerdatemodel显示日期的jspinner。底部的是使用spinnernumbermodel的jspinner。每一个都是通过各自神秘的方式,在本文的后面我们将要学习。
  
 swing指南:spinner model controls(组图)(图一)


  图示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 属性
   swing指南:spinner model controls(组图)(图二)

  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,不同点是绘制了两个箭头。
  
 swing指南:spinner model controls(组图)(图三)
  示图 2. jspinner under different look-and-feel types
  

  集合中的11个uiresource属性在表格2中列举,有限的方法绘制text field和箭头。
  
  table 2. jspinner uiresource 元素
   swing指南:spinner model controls(组图)(图四)
  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 属性
   swing指南:spinner model controls(组图)(图五)

  典型地,唯一的新属性中你将要用来获得最终的日期,尽管所有的结果都被包裹在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 属性
   swing指南:spinner model controls(组图)(图六)

  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 属性
   swing指南:spinner model controls(组图)(图七)

  自定义模型
  
  一般来说,可用的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
   swing指南:spinner model controls(组图)(图八)

  在不知道使用的是哪个模型工作的情况下,在这个级别的你可以做的是改变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属性
   swing指南:spinner model controls(组图)(图九)

  jspinner.listeditor类
  
  当使用spinnerlistmodel类工作时,listeditor不支持任何特殊格式。而是提供了前置类型支持。既然模块的所有入口都知道了,编辑器将尝试匹配用户输入的字符。这里只有一个构造函数,但是你可能几乎用不到。
  
  public jspinner.listeditor(jspinner spinner)
  
  在表格8中将看到listeditor只有一个属性:
  
 swing指南:spinner model controls(组图)(图十)

  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指南:spinner model controls(组图)(图十)

  总结
  
  在这篇文章中,你学习到了swing中的jspinner控件。当你要控制某些选择在一定的范围中时,jspinner可以让你通过翻滚来选择需要的值。你学习到了如何提供这些要选择的值:通过使用spinnerdatemodel和dateeditor,spinnerlistmodel和listeditor,spinnernumbermodel和numbereditor来设置日期。

扫描关注微信公众号