隨筆 - 312, 文章 - 14, 評(píng)論 - 1393, 引用 - 0
          數(shù)據(jù)加載中……

          Java SE 6之GUI:讓界面更加絢麗(下)

          本文為原創(chuàng),如需轉(zhuǎn)載,請(qǐng)注明作者和出處,謝謝!

          Java SE 6之GUI:讓界面更加絢麗( 上)

          在上一篇中我介紹了Java SE 6GUI上的部分改進(jìn)。在這篇 文章中我接著介紹另外幾種新的GUI功能。這些功能是:

          1.  帶有排序和過濾功能的JTable

          2.  增強(qiáng)的JTabbedPane組件

          3.  增強(qiáng)的打印功能

          4.  增強(qiáng)的拖放功能

          一、帶有排序和過濾功能的JTable

              Java SE 6中除了 java.awt被更新外,javax.swing同時(shí)也有了很大的改進(jìn)。在 C/S程序中我們會(huì)經(jīng)常使用到 “表”。如我們可以在查詢數(shù)據(jù)庫(kù)后將查詢結(jié)果顯示在表格中。在Java中顯示表格使用的是JTable類。在以前的版本中,JTable只能簡(jiǎn)單地顯示數(shù)據(jù),并沒有什么附加的處理功能,而在Java SE 6中的JTable增加了排序和過濾功能。用戶可以單擊列頭進(jìn)行排序,也可以根據(jù)某一列來(lái)過濾表中的數(shù) 據(jù)。

          為了使JTable可以對(duì)數(shù)據(jù)進(jìn)行,必須將< /span>RowSorter類和 JTable進(jìn)行關(guān)聯(lián)。 RowSorter是一個(gè)抽象類,它負(fù)責(zé)將 JTable中的數(shù)據(jù)映射成可排序的數(shù)據(jù)。在真正使用時(shí),我們將直接使用 RowSorter的子類TableRowSorter。下面的代碼顯示了如何將 TableRowSorter類和JTable相關(guān)聯(lián)。


          TableModel model = new DefaultTableModel(rows, columns);
          JTable table 
          = new JTable(model);
          RowSorter sorter 
          = new TableRowSorter(model);
          table.setRowSorter(sorter);

          上面代碼首先建立一個(gè)TableModel,然后將這個(gè) TableModel的實(shí)例同時(shí)傳遞給了JTable RowSorter。下面是一個(gè)使用 JTable排序的簡(jiǎn)單的例子。


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

          public class TestSortedTable
          {
              
          public static void main(String args[])
              {
                   JFrame frame 
          =  new JFrame("JTable的排序測(cè)試");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                 
          // 表格中顯示的數(shù)據(jù)
                  Object rows[][] =
                  {
                   { 
          " 王明 ""中國(guó)"44 },
                   { 
          " 姚明 ""中國(guó)"25 },
                   { 
          " 趙子龍 ""西蜀"1234 },
                   { 
          " 曹操 ""北魏"2112 },
                   { 
          " Bill Gates ""美國(guó)"45 },
                   { 
          " Mike""< /span>英國(guó)"33 } };
                  String columns[] 
          =
                   { 
          " 姓名 ""國(guó)籍""年齡" };
                  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 分別是按“姓名”進(jìn)行升序和降序排列的顯示結(jié)果。



          1 按“姓名”升序顯示




          2 按“姓名”降序顯示

              3顯示的是按“年齡”進(jìn)行降序排列。但我們發(fā)現(xiàn)一個(gè)奇怪的問題 ,就是“年齡”字段并不是按數(shù)值類型進(jìn)行排序的,而是按字符類型進(jìn)行排序的。

           


          3 按年齡降序顯示

          出現(xiàn)這種情況是因?yàn)樵谀J(rèn)情況下DefaultTableModal的 列是Object類型。而要想使JTable按數(shù)值進(jìn)行排序,必須要覆蓋 DefaultTableModalgetColumnClass方法。


          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顯示了按“年齡”進(jìn)行排序的界面,看看,是不是按數(shù)值進(jìn)行排序了。



          4 按數(shù)值類型進(jìn)行排序

          下面讓我們來(lái)看看來(lái)何使用JTable進(jìn)行過濾。我們可以 通過convertRowIndexToModel方法進(jìn)行過濾。下面的代碼加在一個(gè)按鈕中添加事件代碼調(diào)用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));
                          }
                      }
                  });

           上面的代碼并沒有調(diào)用convertRowIndextoModel()方法,如果調(diào)用它,你就可以在 表中進(jìn)行相應(yīng)的操作。

          JTable中通過抽象類 RowFilter類對(duì)行進(jìn)行過濾。和排序不同,你可以不建立它們的子類,而使用這個(gè)抽象類的6個(gè)靜態(tài)方法。

          1.     andFilter

          2.         dateFilter(RowFilter.ComparisonType type, Date date, int... indices)

          3.         notFilter(RowFilter<M,I> filter)

          4.         numberFilter(RowFilter.ComparisonType type, Number number, int... indices)

          5.         orFilter

          6.         regexFilter(String regex, int... indices)

          其中andFilter()orFilter()以及 notFilter()方法的功能是將當(dāng)前的過濾條件和其它的過濾條件進(jìn)行組合。如在同時(shí)比較日期和數(shù) 值時(shí)需要將日期過濾和數(shù)值過濾進(jìn)行組合。這些組合是非常簡(jiǎn)單的。

          RowFilter的類型比較允許你進(jìn)行4種關(guān)系的比較,等于 、不等于、大于或小于。我們可以通過指定某一列進(jìn)行過濾,也可以對(duì)所有的列進(jìn)行過濾。這其中最為有趣的也許是正則表達(dá)式過濾(regular expression filter,或簡(jiǎn)稱為regex filter)。使用這個(gè)過濾器可以對(duì)表中數(shù)據(jù)進(jìn)行更高級(jí)的過濾。下面是實(shí)現(xiàn)一個(gè)簡(jiǎn) 單過濾器的代碼。

          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的過濾測(cè)試");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  Object rows[][] 
          =
                  {
                   { 
          " 王明 ""中國(guó)"44 },
                   { 
          " 姚明 ""中國(guó)"25 },
                   { 
          " 趙子龍 ""西蜀"1234 },
                   { 
          " 曹操 ""北魏"2112 },
                   { 
          " Bill Gates ""美國(guó)"45 },
                   { 
          " Mike""< /span>英國(guó)"33 } };
                  String columns[] 
          =
                   { 
          " 姓名 ""國(guó)籍""年齡" };
                  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是上面程序的運(yùn)行界面。



          二、增強(qiáng)的JTabbedPane組件

          JTabbedPane組件為我們提供了一種非常好的方法在窗體上顯示很多的控件。我們可以將不同類別的控 件放到不同的Tab頁(yè)上,然后通過需要點(diǎn)擊相應(yīng)的Tab頁(yè)。在傳統(tǒng)的 Tab頁(yè)上只能防止文本的圖標(biāo)。而在 Java SE 6中使我們可以直接將控件放到 Tab上。我們可以通過 setTabComponentAt方法將控件放到Tab上。這個(gè)方法有兩個(gè)參數(shù),一個(gè)是Tab的索引,另一個(gè)是要放置的對(duì)象。


          JTabbedPane pane = new JTabbedPane();
          pane.setTabComponentAt(
          1, component);

          JTabbedPane控件中有3個(gè)常用的方法,setTabComponentAt(int index, Component comp), getTabComponentAt (int index)indexOfTabComponent(Component)。最后一個(gè)方法將替換Tab上的控件。下面的代碼是一個(gè)關(guān)于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(
          400200);
                  f.setVisible(
          true);
              }
          }


          6是顯示界面,其中在Tab4上插入了一個(gè)文本控件,在Tab1Tab5上各插入了一個(gè) 按鈕控件。




          6 JTabbedPane演示

          三、增強(qiáng)的打印功能

              自從Java SE 5開始, Sun就對(duì)控件的打印功能進(jìn)行了加強(qiáng)。如 JTextFieldJTextArea等。在 Java SE 6Sun為打印增加了分頁(yè)功能。我們只需要調(diào)用 JtextField JTextAreaprint方法就可以調(diào)用打印對(duì)話框。下面是一段測(cè)試代 碼。

          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("打印測(cè)試");
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  
          final JTextArea textArea = new JTextArea();
                  JScrollPane pane 
          = new JScrollPane(textArea);
                  frame.add(pane, BorderLayout.CENTER);
                   textArea.setText(
          "打印 內(nèi)容\r\n可以分頁(yè)! " );
                   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(
          250150);
                  frame.setVisible(
          true);
          }
          }

          7和圖8分別是打印對(duì)話框和設(shè)置對(duì)話框, 點(diǎn)擊“打印“按鈕后彈出如圖8的對(duì)話框。


          7 打印界面

          8 設(shè)置對(duì)話框

              雖然提供了打印設(shè)置對(duì)話框,但我們并無(wú)法設(shè)置如頁(yè)眉(角)等信息,幸運(yùn)的是print的一個(gè)重載為我們提供了這個(gè)功能。下面是這個(gè)方法的參數(shù)。

          public boolean print(MessageFormat headerFormat,

          MessageFormat footerFormat,

          boolean showPrintDialog,

          PrintService service,

          PrintRequestAttributeSet attributes,

          boolean interactive)


          四、增強(qiáng)的拖放功能

          Java SE 6中的拖放功能得到了增強(qiáng),這主要表現(xiàn)在兩個(gè) 方面。

          1.       可以定制拖放模式。

          2.         可以在拖放的過程中加入其它的輔助信息。

              首先需要通過JListJTable等控件的 setDropMode()方法來(lái)設(shè)置一個(gè)拖動(dòng)模式。所有的控件都可以使用 USER_SELECTION模式。這個(gè)模式在以前的Java SE版本中就有。這也是默認(rèn)的拖放模式。

          JListJTableJlist都支持ON模式,這個(gè)模式允許你將對(duì)象拖到其它項(xiàng)的上方。而INSERT模式允許將 一個(gè)對(duì)象插入在其它項(xiàng)之間。而ON_OR_INSERT模式是前3種模式的組合。下面的代碼將演 示一個(gè)拖動(dòng)的例子。


          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(" 拖放測(cè)試" );
                  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(
          300400);
                  f.setVisible(
          true);
              }
          }

          9為拖動(dòng)程序的運(yùn)行界面。在上面的文本框里輸入相應(yīng)的 文本,然后將其選擇再拖動(dòng)到下方的樹中。


          9 拖動(dòng)界面







          Android開發(fā)完全講義(第2版)(本書版權(quán)已輸出到臺(tái)灣)

          http://product.dangdang.com/product.aspx?product_id=22741502



          Android高薪之路:Android程序員面試寶典 http://book.360buy.com/10970314.html


          新浪微博:http://t.sina.com.cn/androidguy   昵稱:李寧_Lining

          posted on 2008-04-30 20:19 銀河使者 閱讀(7923) 評(píng)論(6)  編輯  收藏 所屬分類: java 原創(chuàng)

          評(píng)論

          # re: Java SE 6之GUI:讓界面更加絢麗(下)  回復(fù)  更多評(píng)論   

          不錯(cuò),收藏了!
          2008-04-30 22:01 | gjr

          # re: Java SE 6之GUI:讓界面更加絢麗(下)  回復(fù)  更多評(píng)論   

          說(shuō)不上什么絢麗, 從圖片上看外觀變化不大呀
          我所理解的“絢麗”,是僅看外觀能讓人眼前一亮的東東。
          2008-05-04 09:41 | liigo

          # re: Java SE 6之GUI:讓界面更加絢麗(下)  回復(fù)  更多評(píng)論   

          @liigo
          怎么老盯著這個(gè)不放叻、、、、
          2008-05-05 14:56 | 枯寬

          # re: Java SE 6之GUI:讓界面更加絢麗(下)  回復(fù)  更多評(píng)論   

          并沒有感覺到它絢麗
          2008-05-20 13:28 | 相信

          # re: Java SE 6之GUI:讓界面更加絢麗(下)  回復(fù)  更多評(píng)論   

          絢麗是要自己做的,哈哈,只是演示了功能而已,沒做那么復(fù)雜。
          2008-05-20 15:26 | 銀河使者

          # re: Java SE 6之GUI:讓界面更加絢麗(下)[未登錄]  回復(fù)  更多評(píng)論   

          別轉(zhuǎn)了,這個(gè)有點(diǎn)錯(cuò)誤要更改
          public boolean importData (TransferHandler.TransferSupport support)
          {
          if (!canImport(support))
          {
          return false;
          }
          JTree.DropLocation dropLocation = (JTree.DropLocation)

          suppor.getDropLocat ion();

          應(yīng)該是support.getDropLocat ion();
          2010-03-23 11:22 | dave
          主站蜘蛛池模板: 锦州市| 抚顺市| 潼关县| 响水县| 塔河县| 霍邱县| 尼勒克县| 临湘市| 裕民县| 株洲市| 延安市| 昌吉市| 珲春市| 大竹县| 隆回县| 上饶市| 柳河县| 布尔津县| 鲁甸县| 开阳县| 寻乌县| 北京市| 邛崃市| 赤峰市| 定边县| 高青县| 卓尼县| 砀山县| 日喀则市| 沭阳县| 平塘县| 新宾| 敦化市| 仪陇县| 昌江| 泗阳县| 宝山区| 临朐县| 蕉岭县| 白玉县| 百色市|