2016-03-08 55 views
1

我需要在我的應用程序中實現文件瀏覽功能,同時我意識到可以製作JList項目並手動完成它,但我有一個想法,就是爲此實現JFileChooser。我設法將JFileChooser減少到目錄和文件列表,但我無法覆蓋它的一些功能。我一直在瀏覽源代碼,但沒有運氣。我的想法是它的處理如下:在列表頂部有一個/ ...目錄,所以點擊它時,它會返回到父文件夾。當雙擊目錄時,它將它設置爲當前目錄。當雙擊文件時,它將返回所選文件。重新使用JFileChooser

這是我迄今爲止所使用的代碼:

final JFileChooser fc = new JFileChooser(); 
fc.setControlButtonsAreShown(false); 
fc.setCurrentDirectory(paths[list.getSelectedIndex()]); 
/*remove unwanted components*/ 
for(int i = 0; i < fc.getComponentCount(); i++) { 
    fc.getComponent(0).setVisible(false); 
    fc.getComponent(1).setVisible(false); 
    fc.getComponent(3).setVisible(false); 
} 
add(fc, BorderLayout.CENTER); 

我嘗試添加自定義的MouseListener到JFileChooser中,但沒有奏效。

這是結果我迄今爲止:

enter image description here

任何想法類或聽衆覆蓋/替換所以可達到2種所需的效果,其?

這就是我要尋找一個在視覺方面:

enter image description here

+0

使用JFileChooser內部組件搞亂是不可取的,作爲一個JFileChooser的結構會有所不同從根本上取決於LookAndFeel正在使用中。儘管您仍然可以使用現有的,看不見的JFileChooser中的FileView和FileSystemView,但最好還是構建自己的UI。 – VGR

+0

@VGR如果我得到了正確的選擇,就不需要混淆內部組件。看到我的答案。 – ArcticLord

回答

2

在列表的頂部有一個/ ...目錄等點擊時我 返回到父夾。

JFileChooser具有名稱爲changeToParentDirectory()的方法。所以你可以簡單地添加一個Button並調用該方法。

JButton toParent = new JButton("/.."); 
toParent.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent a) { 
     fc.changeToParentDirectory(); 
    } 
}); 
fc.add(toParent, BorderLayout.NORTH); 

而且雙當目錄點擊它並將其設置爲當前目錄。

您可以設置PropertyChangeListener偵聽只要當前目錄中已經使用雙擊或內部命令改變了觸發JFileChooser.DIRECTORY_CHANGED_PROPERTY財產。

fc.addPropertyChangeListener(new PropertyChangeListener(){ 
    @Override 
    public void propertyChange(PropertyChangeEvent e) { 
     String command = e.getPropertyName(); 
     if (command.equals(JFileChooser.DIRECTORY_CHANGED_PROPERTY)) { 
      File currentDir = fc.getCurrentDirectory(); 
      System.out.println(currentDir.getAbsolutePath()); 
     } 
    } 
}); 

當上雙點擊文件作爲選擇它返回的文件。

您可以設置ActionListener來偵聽JFileChooser.APPROVE_SELECTION通過雙擊選擇文件時觸發的操作。

fc.addActionListener(new ActionListener(){ 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     String command = e.getActionCommand(); 
     if (command.equals(JFileChooser.APPROVE_SELECTION)) { 
      File selectedFile = fc.getSelectedFile(); 
      System.out.println(selectedFile.getAbsolutePath()); 
     } 
    } 
}); 


編輯:

你誤解了我的父文件夾的動作。 Here is an image 來描述它。

這可以通過使用一個操縱FileSystemViewJFileChooser,負責與文件系統的內容交互來實現。我的實現操縱getFiles方法在具有已定義名稱並指向父目錄的列表中走私特殊File
我不太確定這是否是一個非常好的主意,因爲這實際上並不意味着在JFileChooser代碼中,但我們現在就去。

fc.setFileSystemView(new FileSystemView(){ 
    // this method is abstract but since you don't 
    // want to create directories here you don't 
    // need to implement it. 
    @Override 
    public File createNewFolder(File f) throws IOException { 
     return null; 
    } 

    // manipulate the default getFiles method that creates 
    // the list of files in the current directory 
    @Override 
    public File[] getFiles(File dir, boolean useFileHiding){ 
     // get the list of files from default implementation 
     File[] files = super.getFiles(dir,useFileHiding); 
     // get the parent directory of current 
     File parent = getParentDirectory(dir); 
     // skip the next for problematic folders with 
     // empty names and root folders 
     if(!dir.getName().isEmpty() && !isRoot(dir)){ 
      // create a new list of files with one extra place 
      File[] nfiles = new File[files.length + 1]; 
      // add a special file to list that points to parent directory 
      nfiles[0] = new File(parent.getAbsolutePath()){ 
       // set a special name for that file 
       @Override 
        public String getName(){return "...";} 
       }; 
      // add the rest of files to list 
      for(int i = 0; i < files.length; i++) 
       nfiles[i+1] = files[i]; 
      // use the new list 
      files = nfiles; 
     } 
     // return list of files 
     return files; 
    } 

    // some special folders like "c:" gets converted 
    // in shellfolders.Then our setted name "..." would 
    // get converted to "local drive (c:)". This garantees 
    // that our setted name will be used. 
    @Override 
    public String getSystemDisplayName(File f) { 
     return f.getName(); 
    } 
}); 

EDIT2:

是有一個快速的解決方案,以從水平滾動設置垂直 JFileChooser的?

有兩種可能性。簡單的一種是通過將此代碼更改JFileChooserDetails View的風格:

Action details = fc.getActionMap().get("viewTypeDetails"); 
details.actionPerformed(null); 

更復雜的是改變文件視圖JList那就是sun.swing.FilePane一個組件,它是ComponentLayoutOrientationID:2JFileChooser中。
這裏的一個問題是FilePane不是Java庫的一部分,而是核心庫的一部分,默認情況下不可訪問。但是你可以使用反射來獲取現場private JList list;FilePane和與此代碼更改其LayoutOrientationJList.VERTICAL

// get the FilePane Component of JFileChooser 
Object filepane = fc.getComponent(2); 
// get the list field with reflection 
Field field_list = filepane.getClass().getDeclaredField("list"); 
// get access to this private field 
field_list.setAccessible(true); 
// read the value of the field 
JList<?> list = (JList<?>)field_list.get(filepane); 
// change the layout orientation 
list.setLayoutOrientation(JList.VERTICAL); 
+0

如何將JButton添加到JFileChooser?這不是一種黑匣子嗎? –

+0

謝謝,解決方案文件選擇檢測工作,但你誤解我的父文件夾操作。這裏有一張圖片來描述它http://i.imgur.com/Pe10Tzm.png – brainiac080195

+0

嘿,所以你濫用JFileChooser使用BorderLayout並且它的北面沒有被任何東西佔據的事實?可能不是最佳做法。 –