扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
Mustang(也称作Java SE 6),如今刚进入其第二个测试阶段。本文中让我们一起进一步探讨这个新的发行版本中所提供的许多新的特征(从控制台I/O和存取权限控制方法到系统托盘API和表格排序和过滤等)。
在分析控制文件和目录存取许可的若干新的文件方法后,本文将向你展示新的桌面集成API。然后,本文还要分析Mustang的新的编程存取网络参数的能力。最后,本文将讨论表格组件的新的排序与过滤能力。
【注意】我使用Java SE 6的第二个测试版本(build 86)开发并测试了本文的Java示例应用程序,OS平台是Windows 98 SE。
二、 存取权限控制方法
从某种角度看,File类的一个实例其实是一个标识文件系统中文件或目录对象的抽象路径名。文件系统可以限制在这个对象上实现的读、写以及执行等操作。
读、写和执行限制统称为“存取权限”。文件系统可以把多个存取权限集合关联到单个对象。例如,一个集合可以用于对象的所有者而另一个集合可以用于所有的其他用户。
前一个版本中提供的存取权限在直接用于存取对象时,有可能会导致File类的一些方法失败。由于这个原因,Mustang为File类引入了六种新的方法以便让你修改路径名的存取权限:
①“public boolean setExecutable(boolean executable, boolean ownerOnly)”:设置所有者或每个人对于指定抽象路径名的执行许可权。当executable为true时,允许执行操作;而传递给它的值为false时,则不允许执行。把true传递给参数ownerOnly仅允许该抽象路径名的所有者拥有该许可权;当ownerOnly为false,则把该许可权授予每个人。如果底层文件系统无法区分所有者的执行许可与每个人的执行许可,那么,该许可应用于每个人,而不管ownerOnly取值如何。
该方法在成功时返回true;否则,返回false。如果用户无权改变抽象路径名的存取权限或如果底层文件系统没有实现一种执行许可并且executable为false,则方法调用失败。
②“public boolean setExecutable(boolean executable)”:这个方法便于设置所有者对于给定抽象路径名的执行权限。
③public oolean setReadable( oolean readable, oolean ownerOnly)”:设置所有者或每个人对于这个抽象路径名的读取许可权。参数readable为true时允许读取操作;否则,不允许读取。参数ownerOnly为true时仅允许该抽象路径名的所有者拥有该许可权;当ownerOnly为false,则把该许可权授予每个人。如果底层文件系统无法区分所有者的读取许可与每个人的读取许可,那么,该许可应用于每个人,而不管ownerOnly取值如何。
该方法在成功时返回true;否则,返回false。如果用户无权改变抽象路径名的存取权限或如果底层文件系统没有实现一种读取许可并且readable为false,则方法调用会失败。
④“public boolean setReadable(boolean readable)”:这个方法便于设置所有者对于给定抽象路径名的读取权限。
⑤“public boolean setWritable(boolean writable,boolean ownerOnly)”:设置所有者或每个人对于这个抽象路径名的写许可权。参数writable为true时允许写操作;否则,不允许写操作。参数ownerOnly为true时仅允许该抽象路径名的所有者拥有该许可权;当ownerOnly为false,则把该许可权授予每个人。如果底层文件系统无法区分所有者的写许可与每个人的写许可,那么,该许可应用于每个人,而不管ownerOnly取值如何。
该方法在成功时这个方法返回true;否则,返回false。如果用户无权改变抽象路径名的存取权限,则方法调用会失败。
⑥“public boolean setWritable(boolean writable)”:这个方法便于设置所有者对于给定抽象路径名的写权限。
【注意】如果存在一个安全管理器并且它的“public void checkWrite(String file)”方法不允许对文件进行写操作的话,则上面列出的每一个方法都会抛出一个SecurityException异常。
File类还提供了如下对应的方法以帮助你获得一个对象当前设置的读、写和执行权限:
我创建了一个简单的展示setWritable()和canWrite()方法用法的名为WritableDemo的应用程序。在这个应用程序中,你能够使一个文件系统对象可写或仅能读取,而且还能查看这一许可的当前设置。
三、 桌面集成
Sun的Java桌面开发小组引入了若干新的特征以进一步提高Java在桌面开发领域的影响。其中三个著名的特征是:Splash屏幕支持(它让应用程序在启动过程中显示Splash屏幕),系统托盘支持(它让应用程序把图标,提示窗信息和弹出菜单添加到系统托盘),和一组新的桌面API。
现在,我们来讨论桌面API,它有助于无缝地把Java应用程序与桌面集成到一起。该API支持Java应用程序使用一个特定的统一资源标识符(URI)启动操作系统的缺省的浏览器;启动OS的缺省的电子邮件客户端;以及启动应用程序以打开、编辑或打印与该应用程序相关联的文件。
桌面API使用OS的文件关联机制来启动关联到特定的文件类型的应用程序。例如,.doc文件扩展经常与微软的Word关联。经由桌面API,一个Java应用程序能够启动Word以打开、打印或编辑与这个扩展名相关联的文件。
在启动浏览器电子邮件客户端或任何应用程序之前,你的Java应用程序必须决定你的OS是否支持该API。这一决定是通过调用java.awt.Desktop类的“public static boolean isDesktopSupported()”方法实现的。如果OS支持该API,这个方法返回true;否则,它返回false。
在调用isDesktopSupported()之后,该应用程序通过调用Desktop的“public static Desktop getDesktop()”方法继续检索Desktop对象。如果OS不支持键盘输入、显示器或鼠标,这个方法将抛出一个java.awt.Headless异常。如果OS不支持该桌面API,则抛出一个UnsupportedOperationException异常。
现在,既然该Java应用程序已经拥有了一个桌面实例,那么,按下来,它就能够调用各种方法以浏览、发送邮件、打开、编辑或打印。在执行任何这些操作之前,该程序可以调用Desktop的“public boolean isSupported(Desktop.Action action)”方法,如果桌面支持该行为(被描述为适合的Desktop.Action枚举实例),则这个方法返回true。这些Desktop.Action枚举如下:
【注意】在调用相应行为的Desktop方法前,你不必调用“isSupported(Desktop.Action action)”来决定是否支持该行为:你可以直接调用相应的方法,但是之后,你必须处理该方法潜在地抛出的一个UnsupportedOperationException异常。可以从Desktop存取下列行为方法:
①“public void browse(URI uri)”:启动用户缺省的浏览器以显示一个URI—如果浏览器能够处理这个URI的话;否则,它启动该URI缺省的处理器应用程序(这具体要依赖于在java.net.URI类中定义的协议和路径)。
如果uri为null,则抛出一个NullPointerException异常。如果用户的缺省浏览器没有找到或它没能启动或缺省的处理器应用程序没能启动,则抛出一个java.io.IOException异常。
②“public void edit(File file)”:启动相关联的编辑器应用程序并且打开一个文件进行编辑。
如果file为null,则抛出一个NullPointerException异常。如果指定的文件不存在,则抛出一个IllegalArgumentException异常。最后,如果指定的文件相关联的应用程序没能启动,或这个文件没有相关联的编辑器,则抛出一个IOException异常。
③“public void mail()”:启动用户缺省的电子邮件客户端的邮件编辑窗口。
如果用户缺省的电子邮件客户端没有发现或启动失败,则抛出一个IOException异常。
④“public void mail(URI mailtoURI)”:启动用户缺省的电子邮件客户端的邮件编辑窗口,填充由一个“mailto:”URI指定的消息域。这个URI能够指定包括“cc”,“subject”和“body”在内的各种消息域。
如果mailtoURI为null,则抛出一个NullPointerException异常。如果URI的模式不是mailto,则抛出一个IllegalArgumentException异常。如果用户缺省的电子邮件客户端没有发现或启动失败,则抛出一个IOException异常。
⑤“public void open(File file)”:启动相关联的应用程序以打开该文件。如果指定的文件是一个目录,则启动OS的文件管理器以打开它。
如果file为 null,则抛出一个NullPointerException异常。如果指定的文件不存在,则抛出一个IllegalArgumentException异常。最后,如果该指定的文件没有相关联的应用程序,或如果这个应用程序没能启动,则抛出一个IOException异常。
⑥“public void print(File file)”:使用相关联的应用程序的打印命令并使用本地桌面打印设备打印一个文件。
如果file为null,则抛出一个NullPointerException异常。如果指定的文件不存在,则抛出一个IllegalArgumentException异常。如果指定的文件没有相关联的能够用于打印其内容的应用程序,则抛出一个IOException异常。
【注意】如果一个安全管理器存在并且不允许执行要求的行为的话,上面列出的每一个方法都会抛出一个SecurityException异常。
为此,我创建了一个展示桌面API用法的DesktopDemo应用程序。这个应用程序创建了一个包含一系列浏览,邮件,打开,编辑,和打印等单选按钮的GUI界面;还有一个文本域用于输入一个URI或文件名。在输入一个URI或文件名之后,点击适当的按钮便可以从桌面上启动一个应用程序。
在编译和运行DesktopDemo后,在文本域输入一个文件名并点击Open,Edit或Print中的一个按钮以启动该文件相应的应用程序。或输入一个URI并点击“Browse”或“Mail”。图1展示了我已经在文本域中输入了一个邮件URI的屏幕快照。
图1.在此,当输入一个邮件URI时,我没有指定“mailto:”前缀,因为我的电子邮件客户端把这个前缀自动地加入到邮件编辑窗口中的接收者的电子邮件地址的前面。
这个邮件URI仅包含接收者的电子邮件地址和一个主题。当然,我也可以包括正文文本,这可以通过添加“&BODY=”,其后面再跟着一些文本的方法实现。在点击“Mail”单选按钮后,我的电子邮件客户端的邮件编辑窗口中将在正确位置显示接收者的电子邮件地址和主题,如图2所示。
图2.这里所提供的邮件URI还能够指定除主要接收者的电子邮件地址外的其它邮件地址。
四、 以编程方式存取网络参数
Mustang提供了以编程方式存取网络参数的方法—这是通过在java.net.NetworkInterface类和新的java.net.InterfaceAddress类中提供的10个新的方法实现的。这些新引入的网络接口方法列举如下:
①“public byte[] getHardwareAddress()”:以一个字节数组形式返回这个网络接口的硬件地址(通常是机器地址代码,或MAC—也称作以太网地址)。如果这个接口没有一个硬件地址,或如果不能存取这个地址(因为该用户没有足够的权限),则返回null。如果发生一个I/O错误,则抛出一个java.net.SocketException异常。
②“public List
③“public int getMTU()”:返回这个网络接口的最大传输单位(MTU)。该MTU指的是一个通讯协议层能够传递到另一个层的最大包的大小(以字节为单位)。例如,以太网允许的最大MTU是1500字节。根据某一标准(例如以太网)或连接时间(在端到端串行连接时,经常有这种情况),该MTU能够被设置为一个固定长度。如果发生一个I/O错误,则抛出一个SocketException异常。
④“public NetworkInterface getParent()”:如果这个网络接口是一个子接口,则返回这个网络接口的父网络接口(作为一个NetworkInterface实例)。然而,如果这个网络接口是一个物理(非虚拟的)接口或如果这个网络接口是虚拟的并且没有父接口,则返回null。
⑤“public Enumeration
⑥“public boolean isLoopback()”:返回true,如果这个网络接口是一个loopback接口(一种网络接口,在该接口中,外发数据作为输入数据被立即反射回该接口)。如果存在一个I/O问题,则抛出一个SocketException异常。
⑦“public boolean isPointToPoint()”:返回true,如果这个网络接口是一个端到端的接口(例如一个通过调制解调器建立的PPP连接)。如果存在一个I/O问题,则抛出一个SocketException异常。
⑧“public boolean isUp()”:返回true,如果这个网络接口是“up”并且已经“running”。“up”指示已经为这个接口建立起了路由入口。“running”指示要求的系统资源已经分配。如果存在一个I/O问题,则抛出一个SocketException异常。
⑨“public boolean isVirtual()”:返回true,如果这个网络接口是一个虚拟接口(也称作“子接口”)。如果存在一个I/O问题,则抛出一个SocketException异常。
⑩“public boolean supportsMulticast()”:返回true,如果这个网络接口支持多点传送(指一个服务器程序把一个消息的一个副本发送给多个客户端程序的能力)。如果存在一个I/O问题,则抛出一个SocketException异常。
InterfaceAddress类描述了一个网络接口地址。除了通常的实现获得一个哈希代码和获得一个字符串描述等方法之外,这个类还提供了下列三个方法:
【注意】 典型的IPv6值是128(::1/128)或10(fe80::203:baff:fe27:1243/10)。针对IPv4的典型的值是8(255.0.0.0),16(255.255.0.0),或24(255.255.255.0)。
我创建了一个简单的NetParmsDemo应用程序,它展示了NetworkInterface和InterfaceAddress类中提供的许多新的方法。列表3描述了这个应用程序的源代码(见源码文件中的NetParmsDemo.java)。
五、 表格排序与过滤
Swing的表格组件在若干方面得到了增强。其中的一个改进是,支持对一个表格中的行数据进行按升/降序排序并且能够过滤掉其中某些行(所有数据来自于表格模型),并最终显示在组件的视图中。
【请记住】排序和过滤仅对视图有影响,而对模型无影响。
排序和过滤基于一个新概念—行排序器对象,它能够对行数据进行排序(和过滤)。把一个行排序器加入到一个表格组件中的最简单的方法是调用javax.swing.JTable中新引入的“public void setAutoCreateRowSorter(boolean autoCreateRowSorter)”方法,下面的代码片断演示了它的用法:
TableModel model = createTableModel (); JTable table = new JTable (model); table.setAutoCreateRowSorter (true); |
在每次改变模型时,把true传递给setAutoCreateRowSorter()能够使JTable安装一个新的javax.swing.Table.TableRowSorter
注意,当你不想定制行排序器时,你也有可能调用setAutoCreateRowSorter()。但是,在调用这个方法后,你仍然能够定制行排序器,这是通过首先调用JTable的新的“public RowSorter extends TableModel> getRowSorter()”方法以返回当前行排序器来实现的。
因为当你试图把返回的行排序器的引用存储到一个TableRowSorter时编译器会显示一个未检查的警告消息,所以,你可能更喜欢由你自己创建表格行排序器并使用JTable的新的“public void setRowSorter(RowSorter extends TableModel> sorter)”方法来安装它:
TableRowSorter sorter; sorter = new TableRowSorter (model); table.setRowSorter (sorter); |
对TableRowSorter的定制还包括能够使用它的“public void setRowFilter(RowFilter super M,? super I> filter)”方法安装一个行过滤对象(它基于某个标准接收行数据)。这个方法接收一个javax.swing.RowFilter
有些行过滤器可以使用正规表达式。为了获得这种行过滤器,可以调用“RowFilter public static
JTable还提供了其它一些与排序和行过滤有关的新方法。这其中的两个是:“public int convertRowIndexToModel(int viewRowIndex)”和“public int convertRowIndexToView(int modelRowIndex)”,它们分别负责把一个行的索引(根据模型)映射到视图和把一个行的索引(根据视图)映射到模型。
为了向你说明仅是视图为排序和过滤所影响,我使用了前面的TableSortFilterDemo演示应用程序中的一个“convert”方法。在改变行过滤器以后,除了把null传递给TableRowSorter的“public void setSortKeys(List extends RowSorter.SortKey> sortKeys)”方法以打乱视图的排序外,列表4(见本文示例源程序)中其它的内容我们都已经讨论过。
在编译和运行这个应用程序后,通过点击某一列的列头部初始化一个排序。作为响应,所有的行按被点击的列值重新升序或降序排列(每次点击使之在升序与降序之间切换)。选择的列和排序顺序以相应列头部的一个向上/向下的箭头指示,如图3所示。
图3.一个向上箭头表示现在是按升序排序。
除了排序之外,你还能够安装一个过滤器以决定在视图中显示哪些行。为此,只要在文本域中输入一个正规表达式(例如^J或J),并且点击“Set Filter”按钮即可。作为响应,所有的匹配该正规表达式的行都被以非排序方式显示(见图4)。然后,你可以再对这些行进行排序。
图4.点击“Set Filter”对过滤的行建立一个未排序的视图。
六、 结论
除了上面所讨论的新特征之外,Mustang还提供一个编译器API,一个脚本库,一个Java数据库,在JDBC方面也作了新的改进,XML数字签名,更好的国际化,等功能。其它特征还有待于读者自己去探讨。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者