??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲A∨午夜成人片精品网站,中国亚洲女人69内射少妇,亚洲AV电影院在线观看http://www.tkk7.com/xixidabao/category/15386.htmlGROW WITH JAVAzh-cnWed, 28 Feb 2007 04:18:16 GMTWed, 28 Feb 2007 04:18:16 GMT60Java SE 6.0 桌面API~程探讨http://www.tkk7.com/xixidabao/archive/2006/05/26/48366.htmlJAVA之\JAVA之\Fri, 26 May 2006 08:37:00 GMThttp://www.tkk7.com/xixidabao/archive/2006/05/26/48366.html  在默认GUI外观、打印和q行性能斚wQJavaq_一直在努力~小本机应用E序和Java应用E序E序是之间的差距。随着Java SE 6Q代码名为MustangQ的问世Q一些新的功能又被加入,包括新的pȝ托盘功能Q更好的打印支持和桌面APIQjava.awt.Desktop APIQ,从而进一步羃?yu)以上差距。本文中描述的这些新型桌面API允许Java应用E序与主机^C的特定文件类型的默认应用E序q行交互。ؓ了更有效地描q这些APIQ本文还向你展CZ个简单的CZ应用E序DesktopDemo?br />
  一?桌面概述

  q种新功能是由java.awt.DesktopcL提供的。这UAPI来源于JDesktop集成lgQJDICQ工E。该工程的目的是Q得基于Java技术的应用E序成ؓ桌面q_上的"W一{公?Qƈ实现与桌面API的无~集成。具体地_q种新型桌面API允许你的Java应用E序实现如下功能Q?br />
  · 使用一个特定的l一资源标志W(URIQ启动主机系l的默认览?br />
  · 启动Lpȝ的默认电(sh)子邮件客L

  · 启动特定的应用程序以打开、编辑或打印与之相关联的文g

  q些桌面API使用你的L操作pȝ的文件关联以启动与特定文件类型相兌的应用程序。例如,如果开放文档文本(.odtQ文件扩展名与OpenOffice书写器应用程序相兌Q那么你的Java应用E序可以启动OpenOffice书写器以打开、编辑或打印与这U关联相关的文g。根据你的主机系l的不同Q不同的应用E序可能兌不同的行为?br />
  二?q行DesktopDemo应用E序

  DesktopDemo是一个简单Java应用E序-它用了Mustang的桌面API。该应用E序提供了一个主H口Q允怽实现如下三项功能Q?br />
  1. 以一个特定的URI启动默认览器?br />
  2. 用一个邮件接收者启动默认电(sh)子邮件客L?br />
  3. 启动一个相兌的应用程序以打开、编辑或打印文g?br />
  ?昄了这个用h口(UIQ?br />

?QDesktopDemo用户接口

  你可以通过下蝲应用E序源代码及相关的JAR文g来运行这个应用程?把你的控制台的活动目录改变ؓ该应用程序工E的dist目录Qƈ且用一个Mustang JDK执行下列命oQ?br />
java -jar DesktopDemo.jar

  三?定是否支持Desktop API

  在启动浏览器、电(sh)子邮件客L或Q何应用程序之前,DesktopDemo必须定是否你的q_支持q种API。然而,DesktopDemo首先停用所有的囑Ş化的文本域和按钮。在定该^台支持它们之后它该程序才启用q些囑Şlg?br />
  在实例化q些UI后,该应用程序的构造器快速停用这个应用程序的数几个lgQ如下列代码所C:

public DesktopDemo() {
 //初始化所有的GUIlg.
 initComponents();
 // 停用启动览器和?sh)子邮g客户端的按钮
 // 停用打开Q编辑和打印文g的按?br /> disableActions();
 ...
}
/**
* 停用所有的囑ŞlgQ直到我们了?br />* 是否支持它们的功?
*/
private void disableActions() {
 txtBrowserURI.setEnabled(false);
 btnLaunchBrowser.setEnabled(false);

 txtMailTo.setEnabled(false);
 btnLaunchEmail.setEnabled(false);
 rbEdit.setEnabled(false);
 rbOpen.setEnabled(false);
 rbPrint.setEnabled(false);
 txtFile.setEnabled(false);
 btnLaunchApplication.setEnabled(false);
}
...
public javax.swing.JTextField txtBrowserURI;
public javax.swing.JButton btnLaunchBrowser;
public javax.swing.JTextField txtMailTo;
public javax.swing.JButton btnLaunchEmail;
public javax.swing.JRadioButton rbEdit;
public javax.swing.JRadioButton rbOpen;
public javax.swing.JRadioButton rbPrint;
public javax.swing.JTextField txtFile;
public javax.swing.JButton btnLaunchApplication;

  使用Desktop.isDesktopSupported()Ҏ(gu)来确定是否桌面API可用。在Solaris操作pȝ和Linuxq_上,q种API是依赖于Gnome库的。如果这些库不可用,那么q个Ҏ(gu)返回false。在定支持q种APIQ也是_isDesktopSupported()q回trueQ之后,该应用程序就可以使用静态方法getDesktop()来检索一个Desktop实例?br />
Desktop desktop = null;
//在用更多的Desktop API前,首先?br />//是否q种API特定L上的特别的虚拟机所支持?br />if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
...

  如果你的应用E序在调用getDesktop()之前不用isDesktopSupported()q行API支持查,那么它必d备捕获一个UnsupportedOperationException异常-当你的应用程序在一个不支持q种Ҏ(gu)的q_上请求一个Desktop实例时将抛出q种异常。另外,如果你的应用E序q行于一U无键盘、鼠标和监视器环境下Q该getDesktop()Ҏ(gu)抛Z个java.awt.HeadlessException异常?br />
  一旦检索完毕,该Desktop实例卛_怽的应用程序浏览、邮寄、打开、编辑或甚至打印一个文件或URIQ但是只有在被检索的Desktop实例支持q些zd的前提下才行。每个这些活动被UCؓ一个行为(ActionQ,q且每一个行描述Z个Desktop.Action枚D实例Q?br />
  · BROWSE-描述L的默认浏览器执行的一U浏览行?br />
  · MAIL-描述L的默认电(sh)子邮件客L执行的一U邮件行?br />
  · OPEN-描述一U与打开一特定的文件类型相兌的应用程序执行的打开行ؓ

  · EDIT-描述一U与~辑一特定的文件类型相兌的应用程序执行的~辑行ؓ

  · PRINT-描述一U与打印一特定的文件类型相兌的应用程序执行的打印行ؓ


在调用Q何这些行Z前,一个应用程序必ȝ定是否该Desktop实例支持它们。这与确定是否一个Desktop实例可用是有所不同的。这个Desktop.isDesktopSupported()Ҏ(gu)告诉你是否能够创Z个实例。一旦获得一个Desktop对象Q你可以查询该对象来确定支持哪些特定类型的行ؓ。如果该Desktop对象不支持特定的行ؓQ或如果该桌面API本nq不被支持,那么DesktopDemo单地停用那些受媄响的囑Şlg。如?所C,在停用状态下Q不能用这些组件来调用桌面Ҏ(gu)?br />

?Q当不支持桌面API时图形组件被停用?/div>

  通过使用一个新的Desktop实例Q下列代码检查负责是否支持Desktop.Actionq且启用适当的图形组Ӟ

public DesktopDemo() {
 ...
 //在用更多的桌面API前,首先?br /> //是否q种API特定L上的特别的虚拟机所支持?br /> if (Desktop.isDesktopSupported()) {
  desktop = Desktop.getDesktop();
  // 现在Q启用按钮以实现被支持的行ؓ
  enableSupportedActions();
 }
 ...
}
/**
*启用在该L上被支持的行为?br />*q些行ؓ有:打开览器,
*打开?sh)子邮g客户端,和用它们相兌的应用程序打开Q编辑与打印文g?br />*/
private void enableSupportedActions() {
 if (desktop.isSupported(Desktop.Action.BROWSE)) {
  txtBrowserURI.setEnabled(true);
  btnLaunchBrowser.setEnabled(true);
 }

 if (desktop.isSupported(Desktop.Action.MAIL)) {
  txtMailTo.setEnabled(true);
  btnLaunchEmail.setEnabled(true);
 }
 if (desktop.isSupported(Desktop.Action.OPEN)) {
  rbOpen.setEnabled(true);
 }
 if (desktop.isSupported(Desktop.Action.EDIT)) {
  rbEdit.setEnabled(true);
 }
 if (desktop.isSupported(Desktop.Action.PRINT)) {
  rbPrint.setEnabled(true);
 }

 if (rbEdit.isEnabled() || rbOpen.isEnabled() || rbPrint.isEnabled()) {
  txtFile.setEnabled(true);
  btnLaunchApplication.setEnabled(true);
 }
}

  一旦该应用E序定了被支持的行为,它即启用适当的图形组件。如果所有的lg都被启用Q那么相应的UI应该看上d?所C?br />

?Q当支持桌面APIӞ启用lg?/div>

  四?打开览?/b>

  调用下列实例Ҏ(gu)打开你的L的默认浏览器Q?br />
public void browse(URI uri) throws IOException

  因ؓ仅当支持相关联的Desktop.ActionDesktopDemoӞUIlg才被启用Q所以,在实际调用browse()Ҏ(gu)之前Q这个简单的演示应用E序不需要进行行为支持检查。然而,在每一U调用之前检查行为支持在实际中将增加E序的健壮性:

if (desktop.isSupported(Desktop.Action.BROWSE)) {
 //启动览?br /> ...
}

  DesktopDemo把一个java.awt.event.ActionListenerd到每一个按钮上。当被启用时Q?Launch Browser"按钮通过它的ActionListener调用下列Ҏ(gu)Q?br />
private void onLaunchBrowser(java.awt.event.ActionEvent evt) {
 URI uri = null;
 try {
  uri = new URI(txtBrowserURI.getText());
  desktop.browse(uri);
 }
 catch(IOException ioe) {
  ioe.printStackTrace();
 }
 catch(URISyntaxException use) {
  use.printStackTrace();
 }
 ...
}

  q个browse()Ҏ(gu)可能抛出各种cd的异常,q包括:当该URI为null时抛Z个NullPointerException异常Q如果不支持BROWSE行ؓ抛Z个UnsupportedOperationException异常Q如果不能发现或启动一个缺省的览器或应用E序则抛Z个IOException异常Q如果一个安全管理器否定一ơ调用则抛出一个SecurityException异常?br />
  然而,如果一切顺利,那么听取器(ListenerQ将从图4中相联系的文本域中检索文本,创徏一个URIq且调用browse()Ҏ(gu)。上面的代码启动你的系l的默认览器ƈ且指C览器装载该URIQ如?所C?br />

?:使用一个特定URI启动默认览器?br />
?:使用桌面API启动默认览器?/div>



五?发送电(sh)子邮?/b>

  如果支持该行为的话,该应用程序能够启动主机的默认?sh)子邮g客户?通过调用q个Desktop实例Ҏ(gu)Q?br />
public void mail(URI uri) throws IOException
DesktopDemo?Launch Mail"按钮提供了一个ActionListener。在q种情况中,该听取器调用下列Ҏ(gu)Q?br />private void onLaunchMail(java.awt.event.ActionEvent evt) {
 String mailTo = txtMailTo.getText();
 URI uriMailTo = null;
 try {
  if (mailTo.length() > 0) {
   uriMailTo = new URI("mailto"Q?mailToQ?null);
   desktop.mail(uriMailTo);
  } else {
   desktop.mail();
  }
 }
 catch(IOException ioe) {
  ioe.printStackTrace();
 }
 catch(URISyntaxException use) {
  use.printStackTrace();
 }
 ...
}

  该onLaunchMail()Ҏ(gu)从相关的文本域中索电(sh)子邮件接收者,q且在存在一位接收者时使用一Umailto模式的参数创建URIQ然后调用mail()Ҏ(gu)。这个mail()Ҏ(gu)被重载,q样你可以用(或不使用Q一个描q其mailto接收者的URIQ见?Q来调用q个Ҏ(gu)?br />

?:使用一个电(sh)子邮件接收者启动默认电(sh)子邮件客L?/div>

  当创个URIӞ你可以用多个电(sh)子邮件接收者。这个mailto模式支持CCQBCCQSUBJECT和BODY域。例如,可以使用下列文本来创Z个mailto URIQ?br />
mailto:duke@sun.com?SUBJECT=Happy New Year!&BODY=Happy New YearQ?Duke!

  ?昄出相应的l果?br />

?Q桌面API使用多个mailto参数启动默认?sh)子邮g客户端?/div>

  当然Q你也可以不使用参数来调用mail()。在q种情况中,你的?sh)子邮g客户端将启动一个新的没有指定接收者、主题或邮g正文的电(sh)子邮件窗口?

  六?打开、编辑和打印文g

  Java应用E序可以分别使用一个Desktop对象的open()Qedit()和print()Ҏ(gu)来从与其相联pȝ应用E序中打开Q编辑和打印文g(见图8)。同P仅在该Desktop实例支持它们ӞDesktopDemo才允许这些行为,因此在本应用E序环境下,不必再次q行q种支持查?br />

?:启动与一特定的文件类型相联系的应用程序?/div>

  DesktopDemo中的每一个单选按钮也都有它自qActionListener。在q种情况中,每一个单选按钮都讄一个实例变量,以便描述最q选择的按钮的相关联Desktop.ActionQ?br />
Desktop.Action action;
private void onPrintAction(java.awt.event.ActionEvent evt) {
 action = Desktop.Action.PRINT;
}
private void onEditAction(java.awt.event.ActionEvent evt) {
 action = Desktop.Action.EDIT;
}
private void onOpenAction(java.awt.event.ActionEvent evt) {
 action = Desktop.Action.OPEN;
}

  当你按下"Launch Default Application"按钮Ӟ它调用它自己的听取器-q将调用下列Ҏ(gu)Q?br />
private void onLaunchDefaultApplication(java.awt.event.ActionEvent evt) {
 String fileName = txtFile.getText();
 File file = new File(fileName);
 try {
  switch(action) {
   case OPEN:
    desktop.open(file);
    break;
   case EDIT:
    desktop.edit(file);
    break;
   case PRINT:
    desktop.print(file);
    break;
  }
 }
 catch (IOException ioe) {
  ioe.printStackTrace();
 }
 ...
}

  q个Ҏ(gu)军_选择哪个Desktop.Actionq且调用适当的Desktop实例Ҏ(gu)-open()Qedit()或print()。每个方法都需要一个File参数-它被用于执行要求的行为?br />
  有趣的是Q不同的应用E序可以针对甚至相同的文件类型上的这些不同的行ؓq行注册。例如,可以使用OPEN行ؓ启动Firefox览器,使用EDIT行ؓ启动EmacsQ甚至用PRINT行ؓ启动另外不同的应用程序。你的主机桌面的兌用来军_应该调用什么样的应用程序?br />
  注意 使用Mustang中现有桌面API来操作桌面文件关联是不可能的Q而且目前只能使用q_依赖的工h创徏或改变这些关联?br />
  七?ȝ

  桌面集成是Mustang的一个重要主题。Mustang支持q种主题的一U方式是提供一ljava.awt.Desktop API。这UAPI允许Java应用E序启动L的默认浏览器和电(sh)子邮件客L。另外,Java应用E序能够启动与特定的文gcd相关联的应用E序以打开Q编辑和打印文g。尽Java应用E序不能操作Q创建,或改变文件关联,但是q些桌面API定允许Java应用E序启动默认的相兌的应用程?





JAVA之\ 2006-05-26 16:37 发表评论
]]>
Swing指南:Spinner Model Controlshttp://www.tkk7.com/xixidabao/archive/2006/05/08/45052.htmlJAVA之\JAVA之\Mon, 08 May 2006 09:38:00 GMThttp://www.tkk7.com/xixidabao/archive/2006/05/08/45052.html  JSpinner工作h好像是在JList或者JComboBox中间放了一个JFormattedTextField。在JList或者JComboBox中,用户可以提前讑֮好要输入的倹{JSpinner也提供这L一U机制。这个控件的另一个部分是JFormattedTextField。如何显C和输入不由那些的控制格控Ӟ比如JList。相反,可以通过JFormattedTextField来输入或通过边上的两个小头来浏览不同的可用的倹{?br />  
  囄1昄了Spinner伴随不同的输入类型是什么样子。图C?的顶端的JSpinner是一个用来显C法语星期,通过SpinnerListModel。中间的Q是一个通过SpinnerDateModel昄日期的JSpinner。底部的是用SpinnerNumberModel的JSpinner。每一个都是通过各自秘的方式,在本文的后面我们要学习?br />  
 
  囄1.JSpinner实例

  
  要创建和操纵JSpinnerQ许多类都将被调用,最重要的是JSpinner自己。最重要的两个准素集包括SpinnerModel接口Q包括可选择的集合中的选项Q还有,JSpinner.DefaultEditor的实玎ͼ用来捕获所有选择。庆q的是,许多其它调用的类都是在后台工作的Q比如,一旦你lSpinnerNumberModel提供了数字的范围Qƈ且用q个cL协助SpinnerQ你的工作实际上是完成了?br />  
  创徏JSpinner控g
  
  JSpinnercd括两个构造函数来初始化控Ӟ
  
  public JSpinner()
  JSpinner spinner = new JSpinner();
  public JSpinner(SpinnerModel model)
  SpinnerModel model = new SpinnerListModel(args);
  JSpinner spinner = new JSpinner(model);
  
  开始的时候可以没有数据模型,后面可以使用它来跟踪JSpinner的方法。另一个方法,在创个控件的时候用完整的模型Q实现SpinnerModel接口Q它里面有三个具体的子类可以使用QSpinnerDateModelQSpinnerListModel和SpinnerNumberModelQ伴随着他们的抽象父cAbstractSpinnerModel。如果不指名模型Q那么SpinnerNumberModel默认用。而显C和~辑的控件是JFormattedTextFieldQ编辑的基本功能是通过一pdJSpinner的内部类实现的:DateEditorQListEditor和NumberFormatQ还有父cMDefaultEditor的支持?br />  
  JSpinner属?/b>
  
  除了创徏JSpinner对象之外Q你q可以通过表一中的?ji)个属性中的一个来q行配置?br />  
  
Table 1. JSpinner 属?br />   

  value属性中的值允怽更改当前控g的设|,nextValue和perviousValue可以使你以不同的方向察看模型中的入口?br />  
  使用ChangeListener来监听JSpinner events
  
  JSpinner直接支持一U事件监听:changeListener。在别的地方Q当commitEdit()Ҏ(gu)被调用,q个事g被触发Q告诉你spinner的值发生改变。ؓ了证明,列表1联系C个自定义的ChangeListenerQ与囄1的程序相兌?br />  
  列表 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);
  }
  
  q行q个E序可以Clistener的用法(当然Q你也会发现更多关于ChangeListener的有意义的方法)?br />  
  定制JSpinner的外?/b>
  
  同所有的Swing控gQJSpinner在不同的pȝ定义look-and-feelcd下,拥有不同的外观,如示?。这个控件期初看h像一个textfieldQ不同点是绘制了两个头?br />  
 
  C图 2. JSpinner under different look-and-feel types
  

  集合中的11个UIResource属性在表格2中列举,有限的方法绘制text field和箭头?br />  
  Table 2. JSpinner UIResource 元素
   

  SpinnerModel 接口
  
  到目前,我们已经看到了如何同一个主JSpinnerc连接,SpinnerModel接口是控件的数据模型QSpinnerModel的定义如下:
  
  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中的六个Ҏ(gu)直接l制了JSpinnerQ而JSpinner的方法间接调用模块中的方法,在监听的状况下,事g联pd监听器?br />  
  AbstractSpinnerModelc?/b>
  
  AbstractSpinnerModelcd本要实现的是SpinnerModel接口Q它提供了管理和通知的监听列表,子类必须实现接口中的四个Ҏ(gu)QSpinnerModel中的三个具体实现如下QSpinnerDateModelQSpinnerListModel和SpinnerNumberModel?br />  
  SpinnerDateModelc?/b>
  
  从名字可以推断出QSpinnerDateModel提供了数据的选择。这个类有两个构造函敎ͼ一个默认选择所有的数据Q另一个要求你l出范围?br />  
  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);
  
  如果不指名Q何参敎ͼ没有开始和l束炏V下面的例子展示了用参数来表示100q的范围。最后一个成员变量应该是CalendarcM的一个定|
  ·    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
  
  注意QSpinnerDateModel不包含Q何CalendarcM的时间域Q所以不能通过SpinnerDateModel在JSpinner中翻转?br />  
  表格3列出了SpinnerModel中的三个属性,四个关于SpinnerDateModel?br />  
  
Table 3. SpinnerDateModel 属?br />   

  典型圎ͼ唯一的新属性中你将要用来获得最l的日期Q尽所有的l果都被包裹在getValue()中,以适当的数据类型。如果在构造函C提供了数据的表示范围Q那么previous和next的值将是nullQ在边界条g下?br />  
  SpinnerListModel
  
  SpinnerListModel提供了从一个入口列表中选择或者至是字符串表qͼq个cL三个构造函敎ͼ
  
  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);
  
  当没有参数提供时Q这个模型包括一个元素:字符串empty。List版保留一个对list的引用。而不是list的拷贝。如果改变了listQ那么模型中的list也将改变。数l版本的创徏了一个私有的内部c,q且实例化一个list。对于list和数l版本,初始选择的是W一个元素,否则抛Z个IllegalArgumentException异常?br />  
  如表?昄Q属性中增添的是set和get list?br />  
  
Table 4. SpinnerListModel 属?br />   

  SpinnerNumberModelc?/b>
  
  SpinnerNumberModel提供了从一个开区间或闭区间选择数字的模式,数字可以使Numbercȝ所有子c,包括Integer和Double。他有四个构造函数?br />  
  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);
  
  如果最大或最gؓnullQ则为开区间。对于没有参数的Q初始gؓ1Q步qؓ1。步q是整Ş的,如果你设?333Q那么将不会完成?br />  
  表格5展示了SpinnerNumberModel的属性:
  
  
Table 5. SpinnerNumberModel 属?br />   

  自定义模?/b>
  
  一般来_可用的JSpinner模型已经_了,所以没有必要创Z的子cM。但是,q不是所有场合都能满뀂比如,你可能希望用一个包装了SpinnerListModel的模型,代替停止在第一个或最后一个元素,他包装了另一个结束。在列表2中给Z具体实现Q?br />  
  Listing 2. RolloverSpinnerListModel c?br />  
  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~辑?/b>
  
  对于JSpinner每个可用的模型,一个次要的支持c,JSpinner的一个内部类。然而这个模块可以控制控件是否可选,JSpinner~辑器允怽控制如何昄和编辑每个可选的倹{?br />  
  JSpinner.DefaultEditorc?/b>
  
  JSpinner的setEditor()Ҏ(gu)允许你将MJcomponent作ؓJSpinner的编辑器Q当然你可以那样做,更典型的是,你将用JSpinner.DefaultEditor的子cMq行。以JformattedTextField作ؓ单的~辑器工作,提供所有你需要的基本功能。它包括一个基本的构造函敎ͼ
  
  public JSpinner.DefaultEditor(JSpinner spinner)JSpinner spinner = new JSpinner();
  JComponent editor = JSpinner.DefaultEditor(spinner);
  spinner.setEditor(editor);
  
  在表?中可以看刎ͼ有两个属性:
  
  
Table 6. JSpinner.DefaultEditor properties
   

  在不知道使用的是哪个模型工作的情况下Q在q个U别的你可以做的是改变JformattedTextField中的文字昄。更典型的是Q你改变模型编辑器的某些自定义斚w?br />  
  JSpinner.DateEditorc?/b>
  
  DateEditor允许你定制不同的日期昄方式Q用java.text包中SimpleDateFormatcR察看Javadoc了解更多的关于SimpleDateFormat的可用格式模式。如果你不喜Ƣ默认的地显C方式,可以通过l构造函数的W二个参C递一个新参数来改变显C模式?br />  
  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);
  
  默认情况Q格式是M/d/yy h:mm a或?2/25/04 12:34 PM 代表2004q的圣诞节的某个旉。后面的例子要昄2004 December?br />  
  ~辑器的两个属性在表格7中?br />  
  
Table 7. JSpinner.DateEditor属?br />   

  JSpinner.ListEditorc?/b>
  
  当用SpinnerListModelcd作时QListEditor不支持Q何特D格式。而是提供了前|类型支持。既然模块的所有入口都知道了,~辑器将试匚w用户输入的字W。这里只有一个构造函敎ͼ但是你可能几乎用不到?br />  
  public JSpinner.ListEditor(JSpinner spinner)
  
  在表?中将看到ListEditor只有一个属性:
  
 

  JSpinner.NumberEditorc?/b>
  
  NumberEditor和DateEditor的工作方式很怼Q允怽输入定制的显C模式。代替SimpleDateFormat工作QNumberEditor可以协助java.text包中的DecimalFormatcR就像DateEditor一P他又两个构造函敎ͼ
  
  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);
  
  W二个构造函C用默认的字符串格式。如果数字太大,用逗号。如果结果是一个完整的敎ͼ不会用十进制显C?br />  
  表格9中,昄editor的两个属性?br />  
  
Table 9. JSpinner.NumberEditor 属?br />   

  ȝ
  
  在这文章中Q你学习CSwing中的JSpinner控g。当你要控制某些选择在一定的范围中时QJSpinner可以让你通过L来选择需要的倹{你学习C如何提供q些要选择的|通过使用SpinnerDateModel和DateEditorQSpinnerListModel和ListEditorQSpinnerNumberModel和NumberEditor来设|日期?




JAVA之\ 2006-05-08 17:38 发表评论
]]>
Swing 破局Q打造半透明H口 http://www.tkk7.com/xixidabao/archive/2006/05/04/44489.htmlJAVA之\JAVA之\Wed, 03 May 2006 16:26:00 GMThttp://www.tkk7.com/xixidabao/archive/2006/05/04/44489.html  要生成一个半透明的成形窗?而又要避免用本地的~码,唯有灉|地应用screenshot(屏幕快照).

  半透明H口是大众对Swing最为求的Ҏ(gu)之一. 也可以称之ؓ定ŞH口,q种H口有一部分是透明?可以透过它看到桌面背景和其它的程?如果不通过JNI(Java Native Interface 本地接口)Java是无法ؓ我们生成一个半透明的窗口的(即我们可以那样做,q得本地操作q_好支持半透明H口才行).然而这些现状无法阻止我们对半透明H口的?通过一个我最喜欢的手Dscreenshot,我们可以ƺ骗性地实现q个目的.

  仉K这样一个的半透明H口的过E?主要的通过以下几点:
1.在窗口显CZ?先获得一个screenshot;
2.把上一步获取的屏幕快照,作ؓH口的背景图
3.调整位置,以便于我们捕Lscreenshot和实际当前的屏幕完美l合,刉出一U半透明的假?

  刚刚说到的部分只是小儿科,重头戏在?如何在移动或变化半透明H口?及时地更新screenshot,也就是及时更新半透明H口的背?

  在开始我们的旅行之前,先生成一个类Q让它?JPanel,我们用这个承类来捕获屏q?q把捕获的照片作? cȝ具体代码如下?-1

?6Q? ?半透明背景lg
public class TransparentBackground extends Jcomponent {
    private JFrame frame;
    private Image background;

public TransparentBackground(JFrame frame) {
    this.frame = frame;
    updateBackground( );
}
/**
  * @todo 获取屏幕快照后立x新窗口背?br />  */
public void updateBackground( ) {
    try {
        Robot rbt = new Robot( );
        Toolkit tk = Toolkit.getDefaultToolkit( );
        Dimension dim = tk.getScreenSize( );
        background = rbt.createScreenCapture(
        new Rectangle(0,0,(int)dim.getWidth( ),
                          (int)dim.getHeight( )));
    } catch (Exception ex) {
        //p(ex.toString( ));
// 此方法没有申明过Q因为无法得知上下文。因Z影响执行效果Q先注释掉它
        ex.printStackTrace( );
    }
}
public void paintComponent(Graphics g) {
    Point pos = this.getLocationOnScreen( );
    Point offset = new Point(-pos.x,-pos.y);
    g.drawImage(background,offset.x,offset.y,null);
}
}
  首先,构造方法把一个reference保存到父的JFrame,然后调用updateBackground()Ҏ(gu),在这个方法中,我们可以利用java.awt.RobotcL获到整个屏幕,q把捕获到的囑փ保存C个定义了的放|背景的变量? paintComponent()Ҏ(gu)可以帮助我们获得H口在屏q上的绝对位|?q用刚刚得到的背景作为panel的背景图,同时q个背景图会因ؓpanel位置的不同而作对应的移?以panel的背景和panel覆盖的那部分屏幕囑փ无缝重叠在一?同时也就使panel和周围的屏幕兌h.

我们可以通过下面q个mainҎ(gu)单的q行一?随便攄一些组件到panel?再把panel攄到frame中显C?
public static void main(String[] args) {
    JFrame frame = new JFrame("Transparent Window");
    TransparentBackground bg = new TransparentBackground(frame);
    bg.setLayout(new BorderLayout( ));
    JButton button = new JButton("This is a button");
    bg.add("North",button);
        JLabel label = new JLabel("This is a label");
    bg.add("South",label);
    frame.getContentPane( ).add("Center",bg);
    frame.pack( );
    frame.setSize(150,100);
    frame.show( );
}
通过q段代码,q行出的效果如下?Q?所C:

?-1 展示中的半透明H口

  q段代码相当单,却带有两个不之处。首先,如果UdH口Qpanel中的背景无法自动的更斎ͼ而paintComponentQ)只在改变H口大小时被调用Q其ơ,如果屏幕曄发生q变化,那么我们制作的窗口将永远无法和和屏幕背景联合成整体?br />
  谁也不想时不时地跑去更新screenshotQ想想看Q要扑ֈ隐藏于窗口后的东西,要获得一份新的screenshotQ还要时不时的用q些screenshot来更新我们的半透明H口Q这些事情以让用户无法安心工作。事实上Q想要获取窗口之外的屏幕的变化几乎是不太可能的事Q但多数变动都是发生在foregroundH口发生焦点变化或被Ud之时。如果你接受q的观点Q至我接受q个观点Q?那么你可以只监控下面提到的几个事Ӟq只需在这几个事g被触发时Q去更新screenshot?br />public class TransparentBackground extends JComponent
        implements ComponentListener, WindowFocusListener,
        Runnable {
    private JFrame frame;
    private Image background;
    private long lastupdate = 0;
    public boolean refreshRequested = true;
    public TransparentBackground(JFrame frame) {
        this.frame = frame;
        updateBackground( );
        frame.addComponentListener(this);
        frame.addWindowFocusListener(this);
        new Thread(this).start( );
    }
    public void componentShown(ComponentEvent evt) { repaint( ); }
    public void componentResized(ComponentEvent evt) { repaint( ); }
    public void componentMoved(ComponentEvent evt) { repaint( ); }
    public void componentHidden(ComponentEvent evt) { }

    public void windowGainedFocus(WindowEvent evt) { refresh( ); }    
    public void windowLostFocus(WindowEvent evt) { refresh( ); }
  首先Q让我们的半透明H口即panel实现ComponentListener接口,
WindowFocusListener接口和Runnable接口。Listener接口可以帮助我们捕获到窗口的UdQ大变化,和焦点变化。实现Runnable接口可以使得panel生成一个线E去控制定制的repaint()Ҏ(gu)?br />
  ComponentListener接口带有四个component开头的Ҏ(gu)。它们都可以很方便地调用repaint()Ҏ(gu)Q所以窗口的背景也就可以随着H口的移动,大小的变化而相应地更新。还有两个是焦点处理的,它们只调用refresh(),如下C意Q?br />public void refresh( ) {
    if(frame.isVisible( )) {
        repaint( );
        refreshRequested = true;
        lastupdate = new Date( ).getTime( );
    }
}
public void run( ) {
    try {
        while(true) {
            Thread.sleep(250);
            long now = new Date( ).getTime( );
            if(refreshRequested &&
                ((now - lastupdate) > 1000)) {
                if(frame.isVisible( )) {
                    Point location = frame.getLocation( );
                    frame.hide( );
                    updateBackground( );
                    frame.show( );
                frame.setLocation(location);
                    refresh( );
                }
                lastupdate = now;
                refreshRequested = false;
                }
            }
        } catch (Exception ex) {
            p(ex.toString( ));
            ex.printStackTrace( );
        }
    }

  refresh()可以保证frame可见Qƈ适时得调用repaint()。它也会对refreshRequest变量|真(true)Q同时保存当前时间|现在所做的q些Ҏ(gu)下来要做的事是非帔R要的铺垫?br />
  除了每四分之一U被唤醒一ơ,用来是否有新的h的要求或者是否离上次h旉过了一U,Ҏ(gu)run()一般地处于休眠状态。如果离上次h过了一Uƈ且frame是可见的Q那么run()保存frame的位|,隐藏frameQ获取一个screenshotQ更新frame背景Q再Ҏ(gu)隐藏frame时保存的位置信息Q重新显C已l更C背景的frameQ接着调用refreshQ)Ҏ(gu)。通过q样的控Ӟ使得背景更新不至于比需要的多太多?br />
  那么我们Z么要对用一个线E控制刷新如此长大论呢Q一个词Q递归。事件处理可以直接轻村֜调用repaint()Q但是隐藏和昄H口已便于获取screenshot 却交替了很多“得焦”和“失焦”事件。所有这些都会触发一个新的背景更斎ͼDH口再次被隐藏,如此往q,导致永无止境的循环。一个新的“得焦”事Ӟ在执行refresh()几毫U之后被调用Q所以简单地isRecursing标志是无法阻止@环的l箋?br />
  另外Q用户Q意一个改变屏q的动作Q将会随之引Z堆的事g来,而不仅仅是简单一个。应该是最后一个事件去触发updateBackground(),而不是第一个。ؓ了全面解册些问题,代码产生一个线E,然后用这个线E去监控重画QrepaintQ要求,q保证当前的执行动作是发生在q去?000毫秒内没有发生过此动作。如果一个客h五秒不间断地产生事gQ比如,L丢失的浏览窗口)Q那么只有在其它所有工作在一U内完成才执行更新。这样就避免了,用户不至于在Ud东西ӞH口却消׃见了的尴?br />
  另一件烦恼的事就是,我们的窗口仍旧有Ҏ(gu)Q这条边框得我们无法完和背景融ؓ一体。更为痛苦的是用setUndecorated(true)U除Ҏ(gu)Ӟ我们的标题栏和窗口控制栏也跟着U除了。可是这也算不上是什么大问题Q因为那cM用定形窗口的应用E序一般都h可拖动的背景【HackQ?4?br />
  接下来,我们在下面这个简单的试E序中把所讲的东西落实q去Q?br />public static void main(String[] args) {
    JFrame frame = new JFrame("Transparent Window");
    frame.setUndecorated(true);
    
    TransparentBackground bg = new TransparentBackground(frame);
    bg.snapBackground( );
    bg.setLayout(new BorderLayout( ));

   JPanel panel = new JPanel( ) {
        public void paintComponent(Graphics g) {
            g.setColor(Color.blue);
            Image img = new ImageIcon("mp3.png").getImage( );
            g.drawImage(img,0,0,null);
        }
    };
    panel.setOpaque(false);

    bg.add("Center",panel);

    frame.getContentPane( ).add("Center",bg);
    frame.pack( );
    frame.setSize(200,200);
    frame.setLocation(500,500);
    frame.show( );
}
  q段代码通过l承JPanelQ加上一个透明的PNG格式囄Qh工生成一个mp3播放器界面。注意用了setUndecoratedQ)来隐藏边框和标题栏。调用setOpaque(false),隐藏默认的背景Q一般ؓ灰色Q,q样screenshot的背景就可以和图片中透明的部分合成一个整体,去配合程序窗口周围的屏幕背景。(如图6-2Q通过一pd的努力,可以看到图6Q?的效果。是不是很让人惊诧?会不会感叹Java的新版本腄ZQ?br />

?6Q?. mp3 播放器外观模?br />
image  
?6-3. q行中的mp3播放?br />






JAVA之\ 2006-05-04 00:26 发表评论
]]>
վ֩ģ壺 ޵һӰԺ| һ| Ƶ߹ۿ| ޹va| ɫһ| ͵͵߳վý | ŷݵһղsuv| þòþüĻ | ޾Ʒҹר| aëƬëƬѹۿó| ޾AA߹ۿSEE| aѹۿƵ| AVþþƷ| Ʒ͵Ƶۿ | 뿨һ| ëƬƵ߿ѹۿ| ޾Ʒ߹ۿ| Ů˱Ƶվ| ¾þþƷ| ĻƷ| òֻƵ| ޵Ӱѹۿ| 91Ʒѹۿ| ֱƵ| þþƷ7ҹa| ߹ۿwwwѿ| ƷС˵ר| С˵ͼƬQVOD| þWWW˳һƬ| ɫվwww| 97ۺɫ| 91ƷѾþù鶹| ˳ɫ߹ۿ| ˾Ʒҹ侫պ| 91ɫƷ| ӰԺҹˬˬˬ| 91԰Ƶ| ޹ۺ| **aaaaaëƬ| ˳ɵӰ߹ۿ| þۺɫһ|