知识大全 驾驭“野马”-- 探索Java SE 6的一些新特性
Posted 知
篇首语:世事洞明皆学问,人情练达即文章。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 驾驭“野马”-- 探索Java SE 6的一些新特性相关的知识,希望对你有一定的参考价值。
驾驭“野马”-- 探索Java SE 6的一些新特性 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
sun 将要在今年的晚些时候发布最新的Java平台(开发代号Mustang) 作为正式的Java平台 Standard Edition 这个版本关注了几个重要的主题 例如兼容性和稳定性 有关完整的主题列表 参阅Java Specification Request JSE 的版本目录
Mustang预期拥有的新特性包括(除了别的以外) 一个编译器API 控制台输入/输出(I/O) 一个启动画面API 众多的Java D性能改进 XML数字签名 一个系统托盘API java io File类的分区空间方法 Java数据库连接(JDBC) 公共注释(Common annotations) 脚本支持(Scripting) 一个用于XML的流(streaming)API 排序 过滤和加亮javax swing JTable内容的能力 Javadoc标记的更新 可编程操作网络属性(例如广播地址和子网掩码) 方便地打印javax swing text JTextComponent的内容的能力
Mustang拥有远远超出一篇文章探讨范围的新特性 因此 本文只关注新特性的一小部份 确切地说 本文将讨论用于控制台输入/输出和分区空间的方法 用于启动画面以及与系统托盘交互的API
警告由于Mustang目前没有最终发布 一些特性还可能会被改变或者去掉 所以 当Sun公司最终发布Mustang的时候 本文中的一些代码可能会需要改动或者变得完全不相干了
注意我使用Sun公司的Java SDK版本 rc (build )创建和测试了本文的代码 底层平台是Microsoft Windows ME
控制台输入/输出
在 年 月 Sun收到了一个改进控制台输入/输出的增强请求(RFE) 申请人特别要求一种可以提示用户输入密码并且允许用户输入密码(任意长度)而不会在控制台显示出密码字符的方法 申请人指出 抽象窗口工具包(AWT)的setEchoChar()方法并不合用 因为它依赖于GUI的可用性 然而很多基于服务器的操作系统根本不使用GUI
在 年后期 Sun回应了RFE # 为Mustang (build )添加了java io Console类 这个类所提供的方法可以访问与当前虚拟机相关联的基于字符的控制台设备 但是在调用这些方法之前 需要首先调用System的public static Console console()方法来获取一个Console对象 该方法将返回一个用来与控制台设备交互的Console对象 但是如果控制台设备不存在就会返回null 例如当你重定向标准输入或标准输出(或二者皆有)的时候 在调用nsole()来返回Console对象之后 下面的一段代码将检查返回的Console实例是否为null来测定控制台设备是否存在
Console console = nsole () if (console == null) System err println ( Console not available ) return
假设控制台设备是存在的 你可以从控制台输入流读取密码和整行的字符 还可以向控制台输出流写入字符 为了读取密码(而不会将密码字符显示到控制台输出流) 你必须调用Console的两个readPassword()方法之一 这两个方法不允许换行符作为密码的一部分 如果达到了控制台输入流的字符数目限制 他们将返回null
举例来说 你可以调用public char [] readPassword(String fmt Object…… args)来提示用户输入密码 其中提示是由java util Formatter 类型格式化字符串(fmt)和它的变量表(args)来描述的 然后从一个字符数组中返回用户选择的密码 下面的代码段反复调用readPassword(String fmt Object…… args)来提示用户输入密码 直到用户输入了一个字符长度不小于MIN_PWD_LEN的密码为止
char [] pwd do pwd = console readPassword ( Enter password (%d characters min) MIN_PWD_LEN) while (pwd length < MIN_PWD_LEN)
在密码被存储到pwd之后 就可以按需使用了 然而 出于安全性考虑 在不需要使用密码的时候 应该将pwd清零
除了readPassword()方法之外 Console提供了两个readLine()方法以便于从控制台读取一整行的字符 并且将这些字符(不包括换行符)存储在一个String中 如果达到了控制台输入流的字符数目限制 这两个方法都将返回null 举例来说 你可以在不提示用户的情况下 调用public String readLine()来返回一行字符 下列代码段演示了这个方法
关于两个readPassword()方法和两个readLine()方法有一些有趣的事 当这些方法遇到输入/输出错误时 它们不抛出java io IOException对象(例如会被System in read()抛出) 而是抛出一个java io IOError对象 由于IOError是Error的子类 你无需像捕捉IOException那样来捕捉这个对象
向控制台输出流输出字符的配套方法是public Console format(String fmt Object…… args)和作用相同的public Console printf(String fmt Object…… args)方法 后者内部调用了format() 下列代码段演示了printf()
console printf ( %s input)
输出字符之后 format()——和printf()(按扩展名)——自动转储清除控制台输出流
注意控制台对象与唯一的一个java io Reader对象和唯一的一个java io PrintWriter对象相关联 调用控制台的public Reader reader()方法可以返回Reader 例如你可以把Reader传递给java util Scanner的一个构造函数来对控制台输入流进行复杂的解析 调用控制台的public PrintWriter writer()方法可以获取PrintWriter 然后你可以调用各种各样有用的方法来输出不同类型的数据到控制台上 为方便起见 控制台提供了一个public void flush()方法来调用PrinterWriter的flush()方法
让我们用关于控制台输入/输出的知识来做一个实际应用——数据库访问 最终 我建立了一个Microsoft Access sales mdb销售数据库 它随着本文的代码一同发布(可以在资源下载) 该数据库包含一个单独的territories表 它有两列 Name代表售货员的名字 Territory代表售货员可以合法地出售产品的区域 我将下面的数据输入到了数据库中并且为它设置了密码保护——密码是mustang
| —— | | Name | Territory | | —— | | John Doe | North | | Jane Doe | South | | Paul Smith | East | | Kathy Smith | West | | —— |
销售数据库由一个Sales应用软件来访问 在访问数据库之前 程序请求用户输入一个用户名和密码 然后它使用这些数据通过JDBC ODBC bridge驱动来连接sales数据源(你可以用Windows控制面板的ODBC数据源小程序来创建它 用于识别sales mdb的位置) 如果连接成功 程序将输出territories表的全部行和列的值 列表 显示了Sales程序的源代码
Listing Sales java
// Sales javaimport java io * import java sql * import java util * class Sales public static void main (String [] args) throws ClassNotFoundException SQLException // Attempt to obtain a console // 尝试获取控制台 Console console = nsole () if (console == null) System err println ( sales unable to obtain console ) return // Obtain username // 获取用户名 String username = console readLine ( Enter username ) // Obtain password // 获取密码 String password = new String (console readPassword ( Enter password )) // Create a Vector datastructure for holding table records // 建立一个向量数据结构来存储表记录 Vector<Object []> v = new Vector<Object []> () Connection con = null Statement stmt = null ResultSet rs try // Attempt to connect to the sales datasource // 尝试连接sales数据源 con = DriverManager getConnection ( jdbc odbc sales username password) // Garbage collect the password—not a good idea to keep passwords // hanging around // 对密码进行垃圾收集——始终留着密码可不是个好主意 password = null // Attempt to create a statement // 尝试建立一个statement stmt = con createStatement () // Establish the maximum number of rows that can be returned // 设置允许返回的最大行数 stmt setMaxRows ( ) // Attempt to fetch all rows from the territories table // 尝试读取territories表的所有行 String query = SELECT * FROM territories rs = stmt executeQuery (query) // Get number of columns // 获取列数 int nCols = rs getMetaData () getColumnCount () // Read all rows of all columns into storage // 读取所有列的每一行到向量存储 int i = while (rs next ()) Object [] buffer = new Object [nCols] for (int j = j < nCols j++) buffer [j] = rs getObject (j + ) // NOTE getObject requires a based column index // 注意 getObject要求列索引号从 开始 v add (buffer) // Extract rows from the array // 从数组中取出全部行 Object [] rows = v toArray () for (i = i < rows length i++) // Extract columns from the row // 取出一行中的每列值 Object [] cols = (Object []) rows [i] // Print out the values from each column // 显示输出每一列的值 for (int j = j < cols length j++) console printf ( %s cols [j]) console printf ( \\n ) console printf ( Value at Row Col = %s\\n getValue (v )) catch (SQLException e) console printf ( sales %s\\n e getMessage ()) finally if (stmt != null) try stmt close () catch (SQLException e ) if (con != null) try con close () catch (SQLException e ) static Object getValue (Vector v int row int col) // The following conversion should really not be done in this method // because it s inefficient Placing the conversion here is a matter of // convenience // 由于效率低下 下列的转换其实本不该在这个方法中进行 把转换放在这里只是为了方便 Object [] rows = v toArray () Object [] cols = (Object []) rows [row] return cols [col]
编译Sales java然后执行程序 首先呈现在你面的是Enter username 的提示 你可以随意输入任何用户名 但至少要输入点什么 接下来你将被提示输入密码 确定这里要使用mustang 假如连接成功建立了 你将会看到我在上面已经展示的表值
列表 使用了Console的printf()方法来输出表的内容 然而 这种方法有一个不十分明显的问题 如果territories表有很多行的数据 在不滚动的情况下 并不是所有的数据都适合控制台窗口的显示 为了获取这些行 通常需要重定向标准输出到一个文件 但是如果你这样做的话 nsole()将返回null 你也就无法使用控制台输入/输出了 因此 在你的应用中使用Console的printf()和format()方法之前要考虑清楚 不要使用它们向屏幕输出大量的数据 否则你可能就会无法看到全部数据了
注意 仔细地分析列表 的代码 它并没有通过Class forName()来尝试加载JDBC ODBC bridge驱动 由于Mustang支持JDBC ——它提供了一种内在机制来使DriverManager定位和加载驱动类——你不再需要通过Class forName()来显式地加载驱动类了
尽管Console解决了最初的RFE问题 但是很多开发者都对这个类存在异议 主要的批评包括 nsole()方法应该被命名为System getConsole() 然而一些不赞成的人争辩说 get 前缀只应用在bean上面 而System并不是bean 此外 console()是一个静态方法 这意味着IDE将不会认为这个方法是用来获取property的getter方法了 Console类应该提供不使用缓冲来读取单个字符的能力 换句话说 程序不应该等到用户按下回车之后才能读取用户的输入 一个类似C语言的kbhit()函数 通过返回一个Boolean值来判断是否有按键被按下的方法将可以回应这种批评 如果返回true 程序就可以调用另一个方法来返回下一个等待在BIOS按键缓冲中的按键了 Console应该提供打开/关闭控制台字符显示的能力 两个类似C语言中getch()函数(获得字符而不在控制台显示 并且只当没有字符等待在BIOS按键缓冲中时才有效)和getche()函数(获得字符同时在控制台显示 并且只当没有字符等待在BIOS按键缓冲中时才有效)的方法将可以回应这种批评 Console应该提供清除屏幕的能力和其他可以在基于Unix的curses库中找到的特性 Console应该提供一个detach()方法来将应用程序从控制台分离出来并且送入后台
除了第一条之外 对Sun来说 在Mustang的正式版本中回应上述批评的一部份(如果不是全部的话) 也许还不是太晚
分区空间方法在收到改进控制台输入/输出的RFE # 的一个月之前 Sun收到了另外一个RFE 要求提供一种方法来得到可用的磁盘空间 Sun回应了这个RFE # 为File类加入了 个分区空间方法 public long getFreeSpace() 返回以抽象路径名命名的分区的未分配空间字节数 如果抽象路径名不是磁盘分区的名字 返回值为空 public long getTotalSpace() 返回以抽象路径名命名的分区的总磁盘空间 如果抽象路径名不是磁盘分区的名字 返回值为空public long getUsableSpace() 返回以抽象路径名命名的虚拟机可用的空间字节数 如果抽象路径名不是磁盘分区的名字 返回值为空
对于Windows版本的Mustang 这些方法是按照Microsoft的GetDiskFreeSpaceEx函数实现的 让我们基于这个函数的文档重新定义一下这些方法 getFreeSpace() 将返回当前根目录的磁盘的全部空闲字节数 若当前根目录是一个CD ROM驱动器则返回 如果有不可写CD在一个CD RW驱动器中会返回非 值 getTotalSpace()将返回与调用线程相关的用户可用的磁盘字节总数 如果用户配额被开启 这个值可能会小于磁盘的空闲字节总数 getUsableSpace()将返回与调用线程相关的用户可用的磁盘全部空闲字节数 如果用户配额被开启 这个值可能会小于磁盘的空闲字节总数 如果当前根目录是一个CD ROM驱动器则返回 如果有不可写CD在一个CD RW驱动器中会返回非 值
注意很多的现代操作系统允许限制每个用户可用的最大磁盘空间 这个最大空间叫做用户的配额 为用户留出的磁盘空间区域叫做该用户的分区 在这种情况下 getTotalSpace()返回的是与调用线程相关的用户的配额 如果用户没有配额限制(只有一个用户) 该方法返回磁盘字节总数 同样 getUsableSpace()返回的是与调用线程相关的用户的配额限制内的可用字节数 如果用户没有配额限制 该方法则返回磁盘的全部空闲字节数 最后 基于GetDiskFreeSpaceEx()的文档 getFreeSpace()磁盘的空闲字节数——而不考虑用户的配额
列表 展示了一个SpaceChecker程序的源代码 它将显示文件系统的每一个根目录的空闲空间 以及分配给当前用户的可用空间和全部空间
Listing SpaceChecker java
列表 SpaceChecker java
// SpaceChecker javaimport java io File public class SpaceChecker public static void main (String [] args) File [] roots = File listRoots () for (int i = i < roots length i++) System out println (roots [i]) System out println ( Free space = + roots [i] getFreeSpace ()) System out println ( Usable space = + roots [i] getUsableSpace ()) System out println ( Total space = + roots [i] getTotalSpace ()) System out println ()
在我的Windows ME平台上运行该程序时 我观察到了下列信息 A \\ Free space = Usable space = Total space =
C \\ Free space = Usable space = Total space =
M \\ Free space = Usable space = Total space =
N \\ Free space = Usable space = Total space =
由于磁盘配额没有被应用到Windows ME操作系统上 所以C 的空闲空间与可用空间是相同的
启动画面 API
启动画面是基于GUI的现代应用软件的一个重要部分 启动画面不仅可以在漫长的软件启动过程中占据用户的注意力(也可能用来通报用户版本信息或者其他细节) 还可以使用户确定软件正在启动中 这在Java环境中是尤其重要的 因为JVM需要一段时间来加载和启动 图 列举了一个启动画面的例子
图 使用启动画面来显示版权和其他重要信息
Mustang对启动画面的实现是使用一个能够显示GIF(包括动画GIF) PNG或者JPEG图像的无修饰窗口 Java应用程序加载器创建一个启动画面窗口 然后响应命令行参数或者JAR manifest入口 从而在窗口中显示指定的图片 splash命令行参数创建一个启动画面窗口并且显示一个指定的图片 例如 java splash mylogo gif MyApp将创建启动画面窗口并且在这个窗口中显示mylogo gif 确定的图像(见图 ) 然后加载和启动JVM 最后使JVM加载MyApp class并且执行该类的public static void main(String [] args)方法 由于你最有可能把重要的应用打包进一个jar文件 Mustang提供了一个SplashScreen Image manifest项目 用来从jar文件的manifest中访问启动画面的图像 例如SplashScreen Image mylogo gif把mylogo gif识别为在启动画面窗口中显示的图像
假设下列信息被放置在了一个manifest文件中
Manifest Version Main Class MyAppSplashScreen Image mylogo gif
将这个manifest文件 mylogo gif和全部相关的类文件都打包进myApp jar java jar myApp jar会在加载和启动JVM及运行应用程序之前创建启动画面并且显示mylogo gif
如果你调用java splash yourlogo gif jar myApp jar将会发生什么呢?在这种情况下 yourlogo gif将会在启动画面窗口中出现 因为命令行参数 splash优先替代了manifest设置SplashScreen Image
假如你希望在图像上加入视觉效果来定制启动画面 例如为一个有着漫长初始化过程的软件的启动画面图像加入一个动态的进度条来告知用户剩余的时间(参考 Mustang新的启动画面功能 一文中的SplashTest程序) Mustang的java awt SplashScreen类提供了对启动画面定制的支持
在没有启动画面窗口的情况下 一个SplashScreen对象不具有任何意义 所以你不能从SplashScreen类实例化对象 而启动画面窗口只当你指定了 splash命令行选项或者SplashScreen Image manifest项目时才会存在 当你指定了此命令行选项或者manifest项目并且窗口被创建出来 作为其启动过程的一部分 Mustang会创建一个SplashScreen对象 调用SplashScreen的public static SplashScreen getSplashScreen()方法可以返回这个对象的一个实例 切记如果没有启动画面窗口的话 将会返回null 在调用了SplashScreen getSplashScreen()来返回SplashScreen对象之后 下力代码段首先通过检查返回的SplashScreen实例是否为null来测定启动画面窗口是否存在
SplashScreen ss = SplashScreen getSplashScreen () if (ss != null) // Customize the splash screen
假设启动画面窗口是存在的 你可以调用下列五种SplashScreen方法来获取一个图形环境 以便于在缓冲区绘制图象 得到启动画面图象 获取图象的尺寸 用其他图象替换现有图象或者是使用缓冲区中的内容来更新启动画面窗口
public Graphics getGraphics() 以java awt image BufferedImage的形式创建一个覆蓋图象 它具有与启动画面图象相同的尺寸 还有一个窗口 类型设置为BufferedImage TYPE_INT_ARGB(给予图象一个alpha通道来设置透明度) 并且返回一个实例到BufferedImage的图形环境 这幅图象的所有像素都被设为黑色并且是完全透明的 你可以调用图形环境的方法在BufferedImage中绘制 受到绘图操作影响的每个像素都会被分配一个不透明的alpha值 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public URL getImageURL() 以URL返回当前的启动画面图象 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public Dimension getSize() 返回启动画面窗口的尺寸 同时也就是显示的图象的尺寸 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public void setImageURL(URL imageURL) 将启动画面图象改为imageURL确定的图象 当图象被加载 窗口被更新之后 该方法将返回 启动画面窗口将调整为图象的同样大小同时在屏幕上居中 如果imageURL为null 该方法将抛出NullPointerException 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public void update() 更新启动画面窗口使得覆蓋图内容与当前的启动画面窗口的像素相合成 由于采用了Source over合成 覆蓋图象的透明像素可以使启动画面图象的像素显示出来 而覆蓋图象的不透明像素则遮挡了它下面启动画面图象的像素 如果没有调用getGraphics()来创建覆蓋图象 或者在启动画面图象关闭之后它才被调用 它将抛出IllegalStateException
列表 通过一个PhotoAlbum软件的轮廓演示了getSplashScreen() getGraphics() getSize() 与update()这四个方法 这段程序定制了启动画面 在四周加上了一个红色边框 并且在水平中心显示一条信息 Registering plug ins……
Listing PhotoAlbum java列表 PhotoAlbum java
// PhotoAlbum javaimport java awt * public class PhotoAlbum public static void main (String [] args) SplashScreen ss = SplashScreen getSplashScreen () if (ss != null) Graphics g = ss getGraphics () g setColor (Color red) // Color white在我这个版本的Mustang中是默认颜色 Dimension size = ss getSize () // 每个边框宽度都是图象的宽和高中较小值的 % int borderSize if (size width < size height) borderSize = (int) (size width * ) else borderSize = (int) (size height * ) for (int i = i < borderSize i++) g drawRect (i i size width i* size height i* ) // 计算字符串在当前字体时的宽和高 FontMetrics fm = g getFontMetrics () int strWidth = fm stringWidth ( Registering plug ins…… ) int strHeight = fm getHeight () // 在字符串没有超出启动画面窗口范围时 if (strWidth < size width && *strHeight < size height) g setColor (Color blue) g drawString ( Registering plug ins…… (size width strWidth)/ size height *strHeight) // 拷贝覆蓋图象到启动画面窗口 ss update () try Thread sleep ( ) // 暂停 秒钟以便查看图象 catch (InterruptedException e)
为演示PhotoAlbum程序 随本文的代码一起 我加入了一张图片palogo jpg 当你执行java splash palogo jpg PhotoAlbum之后 将首先在屏幕的中间看见palogo jpg的图象 在JVM完成载入并且开始运行main() 你会看见如图 所示的合成图象(也是居中的)
图 标识图片改变了自身的边框颜色 同时提示用户正在注册插件 点击缩略图以观看全尺寸图象
当第一个AWT或者Swing窗口变为可见的时候 启动画面窗口会自动关闭 然而 也许你想要在软件窗口出现之前就将其关闭 或者用你自己的窗口来替换它 SplashScreen类提供了以下 个方法来帮助你达到这个目的 public void close() 隐藏并关闭启动画面窗口 释放分配给该窗口的全部资源 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public Rectangle getBounds() 返回启动画面窗口的边界 如果你调用setImageURL()创建了一个不同尺寸的新启动画面图象 这些边界将会改变 如果在启动画面窗口关闭之后调用这个方法 它将会抛出IllegalStateException public boolean isVisible() 如果启动画面窗口是可见的 将返回一个Boolea值true 在窗口关闭之后调用则返回false
假如你用自己的窗口进行了替换 你可以调用getBounds()来赋予它跟启动画面窗口同样的初始坐标和尺寸 此外 当你自己的窗口变为可见的时候 启动画面窗口将自动关闭
系统托盘API
系统托盘是桌面上一个专门的区域 它显示当前的时间和常驻内存的桌面应用的图标 并且被桌面上当前运行的所有应用共享 表 展示了Windows ME的系统托盘 它位于Windows任务栏的右侧
表 系统托盘上的显示属性应用程序图标相关联的菜单和工具提示
用户只需要适当地轻点鼠标 就随时都可以与这些应用进行交互 例如 当鼠标位于应用软件的图标上时 双击鼠标左键通常就可以打开应用的主窗口(在Windows平台上) 同样地 把鼠标移到应用的图标上面并且单击右键 通常就可以显示特定应用的弹出菜单
Mustang引入了类java awt SystemTray和java awt TrayIcon来与系统托盘进行交互 SystemTray代表桌面的系统托盘 TrayIcon代表可以加入到系统托盘的一个图标
同SplashScreen一样 你不能创建SystemTray对象 而是必须调用SystemTray的public static SystemTray getSystemTray()方法来返回一个代表系统托盘区域的SystemTray实例 由于在底层平台不支持系统托盘时 该方法会抛出UnsupportedOperationException 所以你必须首先调用public static boolean isSupported() 如果系统托盘能得到最低限度的支持(除了显示图标之外 最低限度的支持包括右键点击图标时显示的弹出式菜单 或者是左键双击图标时响应的弹出事件) 这个方法就将返回true 否则返回false 下列代码段演示了获取SystemTray实例的正确方式
if (SystemTray isSupported ()) SystemTray tray = SystemTray getSystemTray () // Do stuff with tray
假设系统托盘可以被支持 你可以调用下列 个方法来实现各种各样的功能 public void add(TrayIcon trayIcon) 为SystemTray加入一个TrayIcon 在这之后 trayIcon所描述的图标将在系统托盘显示出来 图标加入到系统托盘的顺序取决于平台的实现 同样 当应用程序退出或者系统托盘变为不可用的时候 图标将被自动移除 如果trayIcon为null 该方法将抛出NullPointerException 如果你试图多次添加同样的TrayIcon实例 将抛出IllegalArgumentException 如果系统托盘不可用 将抛出AWTException public void addPropertyChangeListener(String propertyName PropertyChangeListener listener) 为trayIcons属性加入一个java beans PropertyChangeListener到listener表 trayIcons属性必须为propertyName的值 当程序从系统托盘添加或者删除一个TrayIcon或者图标被自动移除时 listener将被调用 该方法不抛出任何异常 即使propertyName或者listener为null public PropertyChangeListener [] getPropertyChangeListeners(String propertyName) 返回一个与指定属性相关联的PropertyChangeListener(对于当前程序)的数组 目前只支持trayIcons 并且必须以propertyName值来指定 如果你传递了null或者任何其它值 该方法将返回一个空数组 public TrayIcon [] getTrayIcons() 返回含有被应用程序加入到SystemTray 的全部TrayIcon的一个数组 所返回的数组是真实数组的一个拷贝 可以随意修改而不会反映到系统托盘的图标上 如果没有TrayIcon被加入 该方法将返回一个空数组 public Dimension getTrayIconSize() 以java awt Dimension对象的形式 返回图标出现在系统托盘时将占用的水平和垂直尺寸 其单位是像素 在创建图标之前调用该方法来决定图标的首选尺寸 这是TrayIcon的public Dimension getSize()方法的一种方便的实现 public void remove(TrayIcon trayIcon) 从SystemTray移除指定的TrayIcon 图标将从系统托盘移除 同时将通报所有的属性改变listener 该方法不抛出任何异常 即使trayIcon为null public void removePropertyChangeListener(String propertyName PropertyChangeListener listener) 移除propertyName指定属性的listener propertyName必须是trayIcon(除此之外就没有任何地方需要调用这个方法了) 该方法不抛出任何异常 即使propertyName或者listener为null
表 是一个用来演示上述方法的SystemTrayDemo 程序 这个程序先创建了一个内部为实心红色矩形的实心黄色圆形图标 将这个图标添加到系统托盘 暂停 秒钟 之后从系统托盘将其移除 再暂停 秒钟 然后结束
表 SystemTrayDemo java
// SystemTrayDemo javaimport java awt * import java awt image * import java beans * public class SystemTrayDemo public static void main (String [] args) if (SystemTray isSupported ()) // 获取系统托盘 SystemTray tray = SystemTray getSystemTray () // 注册一个属性变化listener来通知系统托盘上图标的添加和移除 PropertyChangeListener pcl pcl = new PropertyChangeListener () public void propertyChange (PropertyChangeEvent pce) System out println ( Property changed = + pce getPropertyName ()) System out println () TrayIcon [] tia = (TrayIcon []) pce getOldValue () if (tia != null) System out println ( Old tray icon array contents ) for (int i = i < tia length i++) System out println (tia [i]) System out println () tia = (TrayIcon []) pce getNewValue () if (tia != null) System out println ( New tray icon array contents ) for (int i = i < tia length i++) System out println (tia [i]) System out println () tray addPropertyChangeListener ( trayIcons pcl) // 为图标创建一个图象 Dimension size = tray getTrayIconSize () BufferedImage bi = new BufferedImage (size width size height BufferedImage TYPE_INT_RGB) Graphics g = bi getGraphics () g setColor (Color red) g fillRect ( size width size height) g setColor (Color yellow) int ovalSize = (size width < size height) ? size width size height ovalSize /= g fillOval (size width/ size height/ ovalSize ovalSize) // 由该图像创建一个图标并且将其添加到系统托盘 如果不能添加则结束程序 TrayIcon icon = null try tray add (icon = new TrayIcon (bi)) catch (AWTException e) System out println (e getMessage ()) return // 暂停以便查看系统托盘 try Thread sleep ( ) catch (InterruptedException e) // 从系统托盘移除图标 tray remove (icon) // 暂停以查看没有了图标的系统托盘 try Thread sleep ( ) catch (InterruptedException e) // 结束程序 System exit ( )
在获取了系统托盘实例之后 为这个实例注册一个属性改变listener 并且为图标创建一个java awt Image 表 基于这个图标创建了一个TrayIcon对象 然后将该对象加入到系统托盘 这个对象是通过调用TrayIcon s public TrayIcon(Image image)构造器创建的 这个构造器在TrayIcon对象中存储了image 然后 当tray add (icon = new TrayIcon (bi)) 将TrayIcon加入到SystemTray的时候 这个image被取出并且显示在系统托盘上 如果image为null 该构造器和TrayIcon的另外两个构造器都抛出IllegalArgumentException 如果当前平台不支持系统托盘 这些构造器将抛出UnsupportedOperationException
如果你在命令行运行SystemTrayDemo 你将会在系统托盘发现发现一个新图标 在控制台窗口将会获得类似如下的输出 Property changed = trayIcons
Old tray icon array contents
New tray icon array contents java awt TrayIcon@ f c
Property changed = trayIcons
Old tray icon array contents java awt TrayIcon@ f c
几分钟之后 图标就会消失 SystemTrayDemo 程序结束 这对于持续运行的应用来说是不合适的 与此相反 你也许希望当用户右键点击程序图标以弹出菜单 并且选择了适当的项目之后 程序才会结束 你可以用如下方式实现这个行为 创建一个java awt PopupMenu的实例 创立一个带有动作 listener的菜单项目 使用户选择该项即可结束程序 然后将该菜单项加入到弹出菜单中 最后调用public TrayIcon(Image image String tooltip PopupMenu popup)构造器使弹出菜单和图标相关联 与图标的Image和相关联的PopupMenu一起 你可以指定一个String来确定工具提示的文本内容 当鼠标指针移动到图标上面时该文本就会出现 把null传递给tooltip就可以使它不再显示 下列代码段向系统托盘添加了一个带有工具提示和弹出菜单的图标
PopupMenu popup = new PopupMenu () MenuItem miExit = new MenuItem ( Exit ) ActionListener al al = new ActionListener () public void actionPerformed (ActionEvent e) System out println ( Goodbye ) System exit ( ) miExit addActionListener (al) popup add (miExit) TrayIcon ti = new TrayIcon (bi System Tray Demo # popup) tray add (ti) // Assume that tray was previously created // 假定托盘在之前已经被创建了
当用户右键单击鼠标时弹出菜单就会出现 然后用户可以选择菜单的Exit项目来执行菜单项的动作listener 它就可以终止程序
除了鼠标右键动作之外 你也许还希望当用户在图标上使用其它的鼠标动作 例如双击 为了使程序响应这些鼠标动作 TrayIcon提供了下列注册listener的方法 public void addActionListener(ActionListener listener) 为TrayIcon添加一个动作listener 当用户双击图标时 这个listener的public void actionPerformed(ActionEvent e)方法将被调用
你也许想要在多个TrayIcon之间共享一个动作listener 那么决定哪个图标响应动作事件并且调用listener就变得很重要了 你可以通过TrayIcon 的public void setActionCommand(String mand)方法来为其分配一个唯一的指令 然后你就可以在listener中调用java awt event ActionEvent的public String getActionCommand()方法来返回指令名称以及识别TrayIcon 为方便起见 TrayIcon也指定了一个public String getActionCommand()方法
调用TrayIcon的public void removeActionListener(ActionListener listener)方法从TrayIcon上移除listener 你也可以通过调用public ActionListener [] getActionListeners()方法来获取一个含有全部注册的动作listener的数组 public void addMouseListener(MouseListener listener) 为TrayIcon添加一个鼠标listener 当鼠标指针位于图标上方并且用户按下 释放 或者点击鼠标左键时 这个listener的各种方法(除了public void mouseEntered(MouseEvent e)和public void mouseExited(MouseEvent e)不被支持)将会被调用
如果你调用java awt event MouseEvent从父类继承的public Component getComponent()方法 你将得到一个null值 然而 MouseEvent从父类继承的public Object getSource()方法将返回与事件相关联的TrayIcon 调用MouseEvent的public int getX()和public int getY()方法可以得到鼠标坐标 这些坐标是相对于屏幕的——而不是TrayIcon 调用TrayIcon s public void removeMouseListener(MouseListener listener)方法可以从TrayIcon中移除listener 通过调用public MouseListener [] getMouseListeners()可以获取含有所有注册的鼠标listener的一个数组 public void addMouseMotionListener(MouseMotionListener listener) 为TrayIcon添加一个鼠标运动listener 当用户在图标上移动鼠标指针时 这个listener的public void mouseMoved(MouseEvent e)方法将被调用 (public void mouseDragged(MouseEvent e)方法不支持)
再一次 getComponent()返回null getSource()返回一个与事件相关联的TrayIcon getX()和getY()返回的坐标是相对于屏幕的——而不是TrayIcon
调用TrayIcon的public void removeMouseMotionListener(MouseMotionListener listener)方法来从TrayIcon移除listener 你可以通过调用public MouseMotionListener [] getMouseMotionListeners()来得到一个含有全部注册的鼠标动作listener的数组
表 展示了一个拥有自己的String工具提示和PopupMenu的程序SystemTrayDemo 该程序也调用了之前介绍的listener注册方法来注册用于响应动作 鼠标和鼠标运动事件的listener
表 SystemTrayDemo java
// SystemTrayDemo javaimport java awt * import java awt event * import java awt image * import java beans * public class SystemTrayDemo public static void main (String [] args) if (SystemTray isSupported ()) // 获取系统托盘 SystemTray tray = SystemTray getSystemTray () // 为图标创建图像 Dimension size = tray getTrayIconSize () BufferedImage bi = new BufferedImage (size width size height BufferedImage TYPE_INT_RGB) Graphics g = bi getGraphics () g setColor (Color red) g fillRect ( size width size height) g setColor (Color yellow) int ovalSize = (size width < size height) ? size width size height ovalSize /= g fillOval (size width/ size height/ ovalSize ovalSize) try // 创建一个与程序的图标相关联的弹出菜单 选择菜单唯一的一个菜单项就会结束程序 PopupMenu popup = new PopupMenu () MenuItem miExit = new MenuItem ( Exit ) ActionListener al al = new ActionListener () public void actionPerformed (ActionEvent e) System out println ( Goodbye ) System exit ( ) miExit addActionListener (al) popup add (miExit) // 从图像创建一个图标 当鼠标位于图标上方式 选择显示一个工具提示 以及为图标分配弹出式菜单 TrayIcon ti = new TrayIcon (bi System Tray Demo # popup) // 创建并且关联一个listener到图标上 当你采用了适当的动作 例如在Windows下双击鼠标 actionPerformed()方法将会被调用 al = new ActionListener () public void actionPerformed (ActionEvent e) System out println (e getActionCommand ()) ti setActionCommand ( My Icon ) ti addActionListener (al) // 创建并关联一个鼠标listener来记录于图标相关联的鼠标事件 MouseListener ml ml = new MouseListener () public void mouseClicked (MouseEvent e) System out println ( Tray icon Mouse clicked ) public void mouseEntered (MouseEvent e) System out println ( Tray icon Mouse entered ) public void mouseExited (MouseEvent e) System out println ( Tray icon Mouse exited ) public void mousePressed (MouseEvent e) System out println ( Tray icon Mouse pressed ) public void mouseReleased (MouseEvent e) System out println ( Tray icon Mouse released ) ti addMouseListener (ml) //创建并关联一个鼠标运动listener来记录于图标相关联的鼠标运动事件 MouseMotionListener mml mml = new MouseMotionListener () public void mouseDragged (MouseEvent e) System out println ( Tray icon Mouse dragged )  
相关参考
知识大全 Java SE 6 新特性: Instrumentatio
JavaSE6新特性:Instrumentatio 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
JavaSE6新特性:HTTP增强 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 摘要 Jav
JavaSE6新特性:对脚本语言的支持 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
JavaSE6新特性:JMX与系统管理 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
JavaSE6新特性:编译器API 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun公司
JavaSE6新特性:XMLAPI与W 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 年底Sun
JavaSE6调用Java编译器的两种新方法 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!&nbs
知识大全 Java SE 6中XML数字签名标准Java接口
JavaSE6中XML数字签名标准Java接口 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 级
JavaSE6之脚本引擎让程序如虎添翼 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!现在JavaS
让界面更加绚丽JavaSE6.0四种新功能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!