在上一篇中我介绍了 Java SE 6 GUI 上的部分改进。在这篇文章中我接着介绍另外几种新的 GUI 功能。这些功能是:
1.  带有排序和过滤功能的 JTable
2.  增强的 JTabbedPane 组件
3.  增强的打印功能
4.  增强的拖放功能
一、带有排序和过滤功能的 JTable
    Java SE 6 中除了 java.awt 被更新外,javax.swing 同时也有了很大的改进。在 C/S 程序中我们会经常使用到 “表”。如我们可以在查询数据库后将查询结果显示在表格中。在Java 中显示表格使用的是JTable 类。在以前的版本中,JTable 只能简单地显示数据,并没有什么附加的处理功能,而在Java SE 6 中的JTable 增加了排序和过滤功能。用户可以单击列头进行排序,也可以根据某一列来过滤表中的数据。
为了使JTable 可以对数据进行,必须将< /span>RowSorter类和 JTable进行关联。 RowSorter是一个抽象类,它负责将 JTable中的数据映射成可排序的数据。在真正使用时,我们将直接使用 RowSorter的子类TableRowSorter。下面的代码显示了如何将 TableRowSorter类和JTable相关联。

TableModel model  =   new  DefaultTableModel(rows, columns);
JTable table 
=   new  JTable(model);
RowSorter sorter 
=   new  TableRowSorter(model);
table.setRowSorter(sorter);
上面代码首先建立一个TableModel ,然后将这个 TableModel 的实例同时传递给了JTable RowSorter 。下面是一个使用 JTable 排序的简单的例子。

import  javax.swing. * ;
import  javax.swing.table. * ;
import  java.awt. * ;

public   class  TestSortedTable
{
    
public   static   void  main(String args[])
    {
         JFrame frame 
=   new  JFrame( " JTable的排序测试 " );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
//  表格中显示的数据
        Object rows[][]  =
        {
         { 
" 王明 " " 中国 " 44  },
         { 
" 姚明 " " 中国 " 25  },
         { 
" 赵子龙 " " 西蜀 " 1234  },
         { 
" 曹操 " " 北魏 " 2112  },
         { 
" Bill Gates " " 美国 " 45  },
         { 
" Mike " "< /span>英国"33 } };
        String columns[] 
=
         { 
" 姓名 ""国籍""年龄" };
        TableModel model 
= new DefaultTableModel(rows, columns);
        JTable table 
= new JTable(model);
        RowSorter
<TableModel> sorter = new TableRowSorter<TableModel>(model);
        table.setRowSorter(sorter);
        JScrollPane pane 
= new JScrollPane(table);
        frame.add(pane, BorderLayout.CENTER);
        frame.setSize(
300150);
        frame.setVisible(
true);
    }
}
1 和图2 分别是按“姓名”进行升序和降序排列的显示结果。
Java SE 6之GUI:让界面更加绚丽(下)_第1张图片


1 按“姓名”升序显示

Java SE 6之GUI:让界面更加绚丽(下)_第2张图片


2 按“姓名”降序显示
    3 显示的是按“年龄”进行降序排列。但我们发现一个奇怪的问题,就是“年龄”字段并不是按数值类型进行排序的,而是按字符类型进行排序的。
 
Java SE 6之GUI:让界面更加绚丽(下)_第3张图片


3 按年龄降序显示
出现这种情况是因为在默认情况下DefaultTableModal 的列是Object 类型。而要想使JTable 按数值进行排序,必须要覆盖 DefaultTableModal getColumnClass 方法。

TableModel model  =   new  DefaultTableModel(rows, columns)
        {
            
public  Class getColumnClass( int  column)
            {
                Class returnValue;
                
if  ((column  >=   0 &&  (column  <  getColumnCount()))
                {
                    returnValue 
=  getValueAt( 0 , column).getClass();
                }
                
else
                {
                    returnValue 
=  Object. class ;
                }
                
return  returnValue;
            }
        };
  4 显示了按“年龄”进行排序的界面,看看,是不是按数值进行排序了。
Java SE 6之GUI:让界面更加绚丽(下)_第4张图片


4 按数值类型进行排序
下面让我们来看看来何使用JTable 进行过滤。我们可以通过convertRowIndexToModel 方法进行过滤。下面的代码加在一个按钮中添加事件代码调用JTable 的过滤功能。
button.addActionListener( new  ActionListener()
        {
            
public   void  actionPerformed(ActionEvent e)
            {
                String text 
=  filterText.getText();
                
if  (text.length()  ==   0 )
                {
                    sorter.setRowFilter(
null );
                }
                
else
                {
                    sorter.setRowFilter (RowFilter.regexFilter(text));
                }
            }
        });
  上面的代码并没有调用convertRowIndextoModel() 方法,如果调用它,你就可以在表中进行相应的操作。
JTable 中通过抽象类 RowFilter 类对行进行过滤。和排序不同,你可以不建立它们的子类,而使用这个抽象类的6 个静态方法。
1.     andFilter
2.         dateFilter(RowFilter.ComparisonType type, Date date, int... indices)
3.         notFilter(RowFilter filter)
4.         numberFilter(RowFilter.ComparisonType type, Number number, int... indices)
5.         orFilter
6.         regexFilter(String regex, int... indices)
其中andFilter() orFilter() 以及 notFilter() 方法的功能是将当前的过滤条件和其它的过滤条件进行组合。如在同时比较日期和数值时需要将日期过滤和数值过滤进行组合。这些组合是非常简单的。
RowFilter 的类型比较允许你进行4 种关系的比较,等于、不等于、大于或小于。我们可以通过指定某一列进行过滤,也可以对所有的列进行过滤。这其中最为有趣的也许是正则表达式过滤(regular expression filter ,或简称为regex filter) 。使用这个过滤器可以对表中数据进行更高级的过滤。下面是实现一个简单过滤器的代码。
import  javax.swing. * ;
import  javax.swing.table. * ;
import  java.awt. * ;
import  java.awt.event. * ;

public   class  TestFilter
{
    
public   static   void  main(String args[])
    {
         JFrame frame 
=   new  JFrame( " JTable的过滤测试 " );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Object rows[][] 
=
        {
         { 
" 王明 " " 中国 " 44  },
         { 
" 姚明 " " 中国 " 25  },
         { 
" 赵子龙 " " 西蜀 " 1234  },
         { 
" 曹操 " " 北魏 " 2112  },
         { 
" Bill Gates " " 美国 " 45  },
         { 
" Mike " "< /span>英国"33 } };
        String columns[] 
=
         { 
" 姓名 ""国籍""年龄" };
        TableModel model 
= new DefaultTableModel(rows, columns)
        {
            
public Class getColumnClass(int column)
            {
                Class returnValue;
                
if ((column >= 0&& (column < getColumnCount()))
                {
                    returnValue 
= getValueAt(0, column).getClass();
                }
                
else
                {
                    returnValue 
= Object.class;
                }
                
return returnValue;
            }
        };
        
final JTable table = new JTable(model);
        
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
                        model);
        table.setRowSorter(sorter);
        JScrollPane pane 
= new JScrollPane(table);
        frame.add(pane, BorderLayout.CENTER);
        JPanel panel 
= new JPanel(new BorderLayout());
         JLabel label 
=  new JLabel("过滤");
        panel.add(label, BorderLayout.WEST);
        
final JTextField filterText = new JTextField("");
        panel.add(filterText, BorderLayout.CENTER);
        frame.add(panel, BorderLayout.NORTH);
         JButton button 
=  new JButton("过滤");
        button.addActionListener(
new ActionListener()
        {
            
public void actionPerformed(ActionEvent e)
            {
                String text 
= filterText.getText();
                
if (text.length() == 0)
                {
                    sorter.setRowFilter(
null);
                }
                
else
                {
                    sorter.setRowFilter (RowFilter.regexFilter(text));
                }
            }
        });
        frame.add(button, BorderLayout.SOUTH);
        frame.setSize(
300250);
        frame.setVisible(
true);
    }
}
5 是上面程序的运行界面。

Java SE 6之GUI:让界面更加绚丽(下)_第5张图片


二、增强的 JTabbedPane 组件
JTabbedPane 组件为我们提供了一种非常好的方法在窗体上显示很多的控件。我们可以将不同类别的控件放到不同的Tab 页上,然后通过需要点击相应的Tab 页。在传统的 Tab 页上只能防止文本的图标。而在 Java SE 6 中使我们可以直接将控件放到 Tab 上。我们可以通过 setTabComponentAt 方法将控件放到Tab 上。这个方法有两个参数,一个是Tab 的索引,另一个是要放置的对象。

JTabbedPane pane  =   new  JTabbedPane();
pane.setTabComponentAt(
1 , component);
JTabbedPane 控件中有3 个常用的方法, setTabComponentAt(int index, Component comp), getTabComponentAt (int index) indexOfTabComponent(Component) 。最后一个方法将替换Tab 上的控件。下面的代码是一个关于JTabbedPane 控件的演示。

import  javax.swing. * ;
import  javax.swing.table. * ;
import  java.awt. * ;
import  java.awt.event. * ;

public   class  TestTabbedPane
{
    
static   void  addIt(JTabbedPane tabbedPane, String text)
    {
        JLabel label 
=   new  JLabel(text);
        JButton button 
=   new  JButton(text);
        JPanel panel 
=   new  JPanel();
        panel.add(label);
        panel.add(button);
        tabbedPane.addTab(text, panel);
        
if (text.equals ( " tab4 " ))
            tabbedPane.setTabComponentAt(tabbedPane.getTabCount() 
-   1 ,
                              
new  JTextField( " 插入了文本控件 " ));
        
else             
        tabbedPane.setTabComponentAt(tabbedPane.getTabCount() 
-   1 ,
                        button);
    }
    
public   static   void  main(String args[])
    {
         JFrame f 
=   new  JFrame( " JTabbedPane演示 " );
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTabbedPane tabbedPane 
=   new  JTabbedPane();
        addIt(tabbedPane, 
" tab1 " );
        addIt(tabbedPane, 
" tab2 " );
        addIt(tabbedPane, 
" tab3 " );
        addIt(tabbedPane, 
" tab4 " );
        addIt(tabbedPane, 
" tab5 " );
        f.add(tabbedPane, BorderLayout.CENTER);
        f.setSize(
400 200 );
        f.setVisible(
true );
    }
}

6 是显示界面,其中在Tab4 上插入了一个文本控件,在Tab1 Tab5 上各插入了一个按钮控件。

Java SE 6之GUI:让界面更加绚丽(下)_第6张图片


6 JTabbedPane 演示
三、增强的打印功能
    自从Java SE 5 开始, Sun 就对控件的打印功能进行了加强。如 JTextField JTextArea 等。在 Java SE 6 Sun 为打印增加了分页功能。我们只需要调用 JtextField JTextArea print 方法就可以调用打印对话框。下面是一段测试代码。

import  javax.swing. * ;
import  java.awt. * ;
import  java.awt.event. * ;
import  java.awt.print. * ;

public   class  TextPrint
{
    
public   static   void  main( final  String args[])
    {
         JFrame frame 
=   new  JFrame( " 打印测试 " );
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
final  JTextArea textArea  =   new  JTextArea();
        JScrollPane pane 
=   new  JScrollPane(textArea);
        frame.add(pane, BorderLayout.CENTER);
         textArea.setText(
" 打印内容\r\n可以分页! "  );
         JButton button 
=   new  JButton( " 打印 " );
        frame.add(button, BorderLayout.SOUTH);
        ActionListener listener 
=   new  ActionListener()
        {
            
public   void  actionPerformed(ActionEvent e)
            {
                
try
                {
                    textArea.print();                       
                }
                
catch  (PrinterException pe)
                {
                     System.err.println(
" 打印失败 " );
                }
            }
        };
        button.addActionListener(listener);
        frame.setSize(
250 150 );
        frame.setVisible(
true );
}
}
7 和图8 分别是打印对话框和设置对话框,点击“打印“按钮后弹出如图8 的对话框。Java SE 6之GUI:让界面更加绚丽(下)_第7张图片

7 打印界面
Java SE 6之GUI:让界面更加绚丽(下)_第8张图片
8 设置对话框
    虽然提供了打印设置对话框,但我们并无法设置如页眉(角)等信息,幸运的是print 的一个重载为我们提供了这个功能。下面是这个方法的参数。

public boolean print(MessageFormat headerFormat,
MessageFormat footerFormat,
boolean showPrintDialog,
PrintService service,
PrintRequestAttributeSet attributes,
boolean interactive)

四、增强的拖放功能
Java SE 6 中的拖放功能得到了增强,这主要表现在两个方面。
1.       可以定制拖放模式。
2.         可以在拖放的过程中加入其它的辅助信息。
    首先需要通过JList JTable 等控件的 setDropMode() 方法来设置一个拖动模式。所有的控件都可以使用 USER_SELECTION 模式。这个模式在以前的Java SE 版本中就有。这也是默认的拖放模式。
JList JTable Jlist 都支持ON 模式,这个模式允许你将对象拖到其它项的上方。而INSERT 模式允许将一个对象插入在其它项之间。而ON_OR_INSERT 模式是前3 种模式的组合。下面的代码将演示一个拖动的例子。

import  java.awt. * ;
import  java.awt.datatransfer. * ;
import  java.awt.event. * ;
import  java.io. * ;
import  javax.swing. * ;
import  javax.swing.tree. * ;

public   class  TestDrapDrop
{
    
public   static   void  main(String args[])
    {
         JFrame f 
=   new  JFrame( " 拖放测试 " );
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel top 
=   new  JPanel( new  BorderLayout());
         JLabel dragLabel 
=   new  JLabel( " 拖我: " );
        JTextField text 
=   new  JTextField();
        text.setDragEnabled(
true );
        top.add(dragLabel, BorderLayout.WEST);
        top.add(text, BorderLayout.CENTER);
        f.add(top, BorderLayout.NORTH);
        
final  JTree tree  =   new  JTree();
        
final  DefaultTreeModel model  =  (DefaultTreeModel)  tree.getModel();
        tree.setTransferHandler(
new  TransferHandler()
        {
            
public   boolean  canImport (TransferHandler.TransferSupport support)
            {
                
if  ( ! support.isDataFlavorSupported (DataFlavor.stringFlavor)
                        
||   ! support.isDrop())
                {
                    
return   false ;
                }
                JTree.DropLocation dropLocation 
=  (JTree.DropLocation) suppor
                        .getDropLocat ion();
                
return  dropLocation.getPath()  !=   null ;
            }

            
public   boolean  importData (TransferHandler.TransferSupport support)
            {
                
if  ( ! canImport(support))
                {
                    
return   false ;
                }
                JTree.DropLocation dropLocation 
=  (JTree.DropLocation) support
                        .getDropLocat ion();
                TreePath path 
=  dropLocation.getPath();
                Transferable transferable 
=  support.getTransferable();
                String transferData;
                
try
                {
                    transferData 
=  (String) transferable
                          & nbsp; .getTransferData(DataFlavor.stringFlavor);
                }
                
catch  (IOException e)
                {
                    
return   false ;
                }
                
catch  (UnsupportedFlavorException e)
                {
                    
return   false ;
                }
                
int  childIndex  =  dropLocation.getChildIndex();
                
if  (childIndex  ==   - 1 )
                {
                    childIndex 
=  model.getChildCount(path
                          & nbsp; .getLastPathComponent());
                }
                DefaultMutableTreeNode newNode 
=   new  DefaultMutableTreeNode(
                        transferData) ;
                DefaultMutableTreeNode parentNode 
=  (DefaultMutableTreeNode) path
                        .getLastPathC omponent();
                model.insertNodeInto (newNode, parentNode, childIndex);
                TreePath newPath 
=  path.pathByAddingChild(newNode);
                tree.makeVisible(newPath);
                tree.scrollRectToVisible(tree.getPathBounds(newPath));
                
return   true ;
            }
        });
        JScrollPane pane 
=   new  JScrollPane(tree);
        f.add(pane, BorderLayout.CENTER);
        JPanel bottom 
=   new  JPanel();
        JLabel comboLabel 
=   new  JLabel( " DropMode " );
        String options[] 
=
        { 
" USE_SELECTION " " ON " " INSERT " " ON_OR_INSERT "  };
        
final  DropMode mode[]  =
        { DropMode.USE_SELECTION, DropMode.ON, DropMode.INSERT,
                DropMode.ON_OR_INSERT };
        
final  JComboBox combo  =   new  JComboBox(options);
        combo.addActionListener(
new  ActionListener()
        {
            
public   void  actionPerformed(ActionEvent e)
            {
                
int  selectedIndex  =  combo.getSelectedIndex();
                tree.setDropMode(mode[selectedIndex]);
            }
        });
        bottom.add(comboLabel);
        bottom.add(combo);
        f.add(bottom, BorderLayout.SOUTH);
        f.setSize(
300 400 );
        f.setVisible(
true );
    }
}
9 为拖动程序的运行界面。在上面的文本框里输入相应的文本,然后将其选择再拖动到下方的树中。
Java SE 6之GUI:让界面更加绚丽(下)_第9张图片
9 拖动界面

Java 6 GUI Java SE

0

收藏

上一篇:Struts2教程8:拦截器概述 下一篇:Java SE 6之GUI:让界...
Java SE 6之GUI:让界面更加绚丽(下)_第11张图片
androidguy 专栏作者

355篇文章,222W+人气,134粉丝

欧瑞科技创始人&CEO,IT畅销书作家,

关注
Java SE 6之GUI:让界面更加绚丽(下)_第12张图片

Ctrl+Enter 发布

发布

取消

推荐专栏更多

Java SE 6之GUI:让界面更加绚丽(下)_第13张图片
基于Python的DevOps实战

自动化运维开发新概念

共20章 | 抚琴煮酒

¥51.00 494人订阅
订   阅
Java SE 6之GUI:让界面更加绚丽(下)_第14张图片
微服务技术架构和大数据治理实战

大数据时代的微服务之路

共18章 | 纯洁微笑

¥51.00 688人订阅
订   阅

猜你喜欢

用Go语言异常机制模拟TryCatch异常捕捉 Python从菜鸟到高手(18):类与方法的私有化 Java多线程编程总结 Java关键字final、static使用总结 java万年历简单制作 体验vSphere 6之1-安装VMware ESXi 6 RC版 Java内部类的使用小结 Java中的main()方法详解 Java相对路径读取文件 Java线程:创建与启动 Java线程:线程的同步与锁 深入研究java.lang.ThreadLocal类 别翻了,这篇文章就是要让你搞定Java多线程! 惊讶!线上四台机器同一时间全部 OOM,到底发生了什么? 原创001 | 搭上SpringBoot自动注入源码分析专车 干货,记一次Metaspace导致频繁fgc的问题排查过程 浅谈集群版Redis和Gossip协议 一文带你深入了解 Redis 的持久化方式及其原理 Sprint Boot如何基于Redis发布订阅实现异步消息系统的同步调用? 分布式应用监控:SkyWalking 快速接入实践
Java SE 6之GUI:让界面更加绚丽(下)_第15张图片
Java SE 6之GUI:让界面更加绚丽(下)_第16张图片

扫一扫,领取大礼包

0

分享
Java SE 6之GUI:让界面更加绚丽(下)_第17张图片
关注
专栏作者 androidguy
Java SE 6之GUI:让界面更加绚丽(下)_第18张图片