so true

          心懷未來,開創(chuàng)未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0

          導(dǎo)航

          <2007年12月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          常用鏈接

          留言簿(8)

          隨筆分類(157)

          隨筆檔案(158)

          牛人博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          [轉(zhuǎn)載]使用Regex實(shí)現(xiàn)的為JFileChooser使用的FileFilter對象的創(chuàng)建類

          在使用swing的程序中經(jīng)常用到JFileChooser,并且經(jīng)常需要自定義一個FileFilter的子類來在文件列表中屏蔽不需要的文件。

           

          大多數(shù)情況下,該子類是這樣設(shè)計的:

          public ImgFileFilter

          extends FileFilter{

              public boolean accept(File f) {

                 if (f.isDirectory()) {

                  return true;

                 }

                 // Utils is a user custom utility class, getExtension

                 // is used to return the extension of a file.

                  String extension = Utils.getExtension(f);

                 if (extension != null) {

                 if (extension.equals(Utils.tiff) ||

                     extension.equals(Utils.tif) ||

                     extension.equals(Utils.gif) ||

                     extension.equals(Utils.jpeg) ||

                     extension.equals(Utils.jpg) ||

                     extension.equals(Utils.png)) {

                         return true;

                 } else {

                     return false;

                 }

                 }

                  return false;

              }

              public boolean getDescription(){

                  return "Image Files.";

              }

          }

           

          這段代碼取自sun公司的"Java Tutorial". 正象你所看到的,accept(File file)方法決定一個文件是否顯示,如果返回值為true則顯示反之屏蔽。

          麻煩的是如果你要使用多項文件類型選擇,比如在EditPluse里,你可以選擇打開*.txt, *.cpp, *.java等文件。為了這類需求,你不得不一個一個為不同的文件選擇設(shè)計不同的FileFilter。有沒有更方便的方法來實(shí)現(xiàn)FileFilter呢?我設(shè)計了一個工具類可以解決這個問題,使用它,幾行代碼就可以完成一個JFileChooser的設(shè)計:

           

              JFileChooser chooser = new JFileChooser();

              FileFilterBuilder builder = FileFilterBuilder.newInstance().

                     chooser.setFileFilter(

                         builder.createFileFilter(

                             "*.tiff;*.tif;*.gif;*.jpeg;*.jpg;*.png"

                             ,"Image Files(*.tiff;*.tif;*.gif;*.jpeg;*.jpg;*.png)"));

                     chooser.setFileFilter(

                         builder.createFileFilter(

                             "*.cpp;*.h",

                            "Cpp Files(*.cpp;*.h)"));

                     chooser.setFileFilter(

                         builder.createFileFilter(

                             "exam*.cpp;exam?.h",

                            "example Files(*.cpp;*.h)"));

           

                     chooser.showOpenDialog(null);

           

          僅僅是這幾行代碼就實(shí)現(xiàn)了第一個程序的功能,另外,還增加了一個選擇cpp文件的功能和一個選擇以exam開頭的cpp文件或以exam開頭的后跟一個字符的.h文件。下面,我將把我的設(shè)計介紹個大家。

           

          jsdk1.4開始,在java.util.regex出現(xiàn)了一個新的javaPattern。Pattern是一個編譯了的正則表達(dá)式的。它有很強(qiáng)大的功能,在這里我只使用其中一點(diǎn)點(diǎn)。在Pattern類中有一個方法matches(String regex, CharSequence input)可以判斷是否一個input可以與一個regex向符合。"regex""regular expression"的縮寫, 一個正則表達(dá)式是一個字符串模型, Windows中文件名模型一樣, 比如, "*.exe" 就是一個可以包括所有可執(zhí)行文件的文件名模型。

           

          到這里,你會猜到我要做什么了。首先,我介紹幾個程序中用到的regex的特征。

           

          在一個regex中,字符"."代表任何一個字符,".*"代表零個或多個字符,".{n}"代表n個任意字符。我們可以作一個測試。

          import java.util.regex.Pattern;

          public class TestRegex {

              public static void main(String[] args) {

                  String regex, input;

           

                 regex = args[0];

                 input = args[1];

                  boolean isMatch = Pattern.matches(regex, input);

           

                  System.out.println(isMatch);

              }

          }

           

          上面代碼中,args[0]是一個你提供的regex,args[1]是一個待判定的字符串,如果該字符串與regex相符,程序?qū)⒋蛴?/span>True,否則,false。通過提供不同的運(yùn)行參數(shù)并查看運(yùn)行結(jié)果,可以幫助你了解regex。

           

          我們知道,在windows文件名模型中"?"代表一個字符,與regex中的".{1}"相對應(yīng);"*"代表0個或多個字符,與regex中的".*"相對應(yīng)。如果一個字符串中包含"????",那么,對應(yīng)的,我們可以在regex中使用".{4}"與之匹配。最后一個重要的事情是對于字符"."regex應(yīng)該使用"[.]"與之對應(yīng)。

           

          好了,事情結(jié)束了,正象你所猜測的,我的設(shè)計的核心是把windows的文件名模型轉(zhuǎn)換成regex,然后使用這個regex來決定那些文件可以顯示,那些文件不顯示。下面列出所有代碼。

           

          /*

           * @(#)FileFilterBuilder.java  1.0 06/01/03

           * @author Unagain

           */

           

          package je14tut.dom;

           

          import java.io.File;

          import java.util.regex.Pattern;

           

          import javax.swing.filechooser.FileFilter;

           

          /**

           * The <code>FileFilterBuilder</code> class is a singleton, it can create

           * a appropriate <code>FilterFilter</code> object for a <code>JFileChooser</code> object

           * in your code, rather than to write a subclass of FileFilter manually.

           * <p>

           * You can use <code>newInstance</code> to obtain the only instance, and use

           * <code>createFileFilter</code> to get the <code>FileFilter</code>.

           *

           * @author Jason

           *

           */

           

          public class FileFilterBuilder {

              static FileFilterBuilder INSTANCE;

             

              static final int NAME = 0;

              static final int EXT = 1;

           

              private FileFilterBuilder() {}

             

              /**

               * create and get the singleton instance.

               * @return FileterBuilder.

               */

             

              public static FileFilterBuilder newInstance() {

                  if (INSTANCE == null) {

                      INSTANCE = new FileFilterBuilder();

                  }

                  return INSTANCE;

              }

             

              /**

               * The only functional method in this class so far, used to create a appropriate

               * <code>FileFilter</code> instance you perferred based on a windows system file pattern

               * you given.

               *

               * @param winFilePattern - A window system file pattern, such as "*.java", "new*.*",

               * "ex?mp*.exe", etc.

               * <blockquote>you can specified two or more pattern once, split each other with ";", for example

               * "*.java;*.html", etc. </blockquote>

               * @param description

               * @return

               */

             

              public FileFilter createFileFilter(String winFilePattern, final String description) {

             

              final String pattern = PatternBuilder.createFileRegex(winFilePattern);

             

                  FileFilter filter =

                      new FileFilter() {

                           

                          public boolean accept(File f) {

                            if (f.isDirectory()) {

                                return true;

                            }

                            return Pattern.matches(pattern, f.getName().toLowerCase());

                        }

                          public String getDescription() {

                            return description;

                        }

                  };

                  return filter;

              }

          }

           

          /**

           * <code>PatternBuilder</code> has only one methoes so far, it just as a translator to convert a

           * windows system file pattern to a java regular expression for <code>FileFilterBuiolder</code>.

           * In fact it is more power than FileFilter needed, for Considering possibly usage in future, I

           *  separate it from <code>FileFilterBuiolder</code>.

           * @author Jason

           */

          class PatternBuilder {

              private PatternBuilder() {}

             

              public static String createFileRegex(String filePattern) {

             

                  StringBuffer regex = new StringBuffer();

                  boolean lastIsQueMark = false;

                  int queMarkCount = 0;

                 

                  filePattern = filePattern.toLowerCase();

                 

                  for (int i=0; i<filePattern.length(); i++) {

                  char chr = filePattern.charAt(i);

                 

                  if (chr == '?') {

                          if (!lastIsQueMark) {

                              regex.append(".{");               

                              lastIsQueMark = true;               

                        }

                          queMarkCount ++;

                  } else {

                      

                          if (lastIsQueMark) {               

                            regex.append(queMarkCount);

                            regex.append("}");                  

                            queMarkCount = 0;

                            lastIsQueMark = false;

                        }

                       

                          switch(chr){

                          case '*':

                              regex.append(".*");

                              break;

                          case '.':

                              regex.append("[.]");

                              break;

                          case ';':

                              regex.append("|");

                              break;

                          default:                   

                              regex.append(chr);

                          }

                  }

                 

                  }

                 

                  return regex.toString();

              }

          }

          posted on 2007-12-29 20:39 so true 閱讀(523) 評論(0)  編輯  收藏 所屬分類: Java

          主站蜘蛛池模板: 宜良县| 梧州市| 怀安县| 乌鲁木齐市| 浮梁县| 太仆寺旗| 广平县| 浦北县| 宣汉县| 北京市| 尉氏县| 霍城县| 淮北市| 道真| 邵武市| 清远市| 兴义市| 阳江市| 岳阳县| 含山县| 山阴县| 柳林县| 伊通| 台中县| 丰顺县| 大石桥市| 平凉市| 兴文县| 镇雄县| 荆州市| 昔阳县| 大姚县| 灵寿县| 会理县| 城口县| 仪征市| 中江县| 贵南县| 怀宁县| 会昌县| 绥宁县|