2010-11-20 97 views
5

對Swing Pros的問候,這是一個很好的(我希望)問題。改變JFileChooser的行爲:防止在文件路徑中輸入「選擇」JTextField

以下是我看到的任務要求和可能的解決方案。我希望有人有這樣的核心經驗分享一些想法。

這不需要編碼或類似的東西,我只需要一般建議哪個方法更可靠的有關事實,我需要它駐留在sun.swing和/ 私人符號工作或javax.swing.plaf包。

任務是修改/改變JFileChooser行爲(實際上只是一點點)。

  1. 當用戶按下文件名的JTextField進入,並且該字段包含的目錄路徑

    ,沒有「選擇」的目錄,但切換到它代替。是的,該對話框被配置爲接受目錄,但我們只需要接受點擊「打開」按鈕,並(可能)雙擊文件列表表格。

    一個:

  2. 通過打擊在文件名的文本字段

我這裏還有幾個通用的解決方案選項輸入阻止用戶選擇與超過1GB的數據更多的是目錄/文件。聽取JFileChooser提供的基於屬性的更改(其中AFAICS是事後觸發的,並且不會提供我們需要的控制級別)。

b。與javax.swing.plaf.basic.BasicFileChooserUI中鼓搗(通過refrection,打破了私有級封裝),並改變參考

private Action approveSelectionAction = new ApproveSelectionAction(); 

使我們的自定義操作做額外的檢查1和2本與plaf包鏈接,並且可能會失敗,如果在此UI類下面的某個類中以某種方式覆蓋此操作。

c。遍歷JFileChooser組件層次結構,找到JTextField(顯然應該只在組件樹中出現一次),使用我們的自定義檢查來修飾掛在該JTextField上的所有動作偵聽器。我的調試會話顯示這個JTextField是生活在sun.swing.FilePane中的JTextField的一些匿名子類。 這種方法似乎對OO更友好,但對於某些操作系統來說,這個文本字段不存在,或者其他一些JTextField也存在於層次結構中。

好吧,公共JFileChooser API似乎不足以實現這種行爲,而另外兩種選擇是深魔法或不可移植(長期),或者甚至兩者。

所以,問題是:你會選擇哪種方法,爲什麼?

回答

5

關於選項2,您不需要使用反射來自定義接受操作。您可以重寫approveSelection()方法。例如:

JFileChooser chooser = new JFileChooser(new File(".")) 
{ 
    public void approveSelection() 
    { 
     if (getSelectedFile().exists()) 
     { 
      System.out.println("duplicate"); 
      return; 
     } 
     else 
      super.approveSelection(); 
    } 
}; 
+0

哦,我dumbo,我會測試,並報告我的發現。 – 2010-11-21 22:12:25

+0

嗯,我完全可以通過在某些應該被認爲無效的情況下不調用super.approveSelection()來攔截和解除批准選擇事件。這是一個不錯的解決方案,再次感謝。 – 2010-12-09 22:03:43

3

我最近遇到了同樣的要求,即,在JFileChooser的JTextField中按下Enter將導致顯示的對話框遍歷目錄而不是從對話框返回。只有點擊打開按鈕纔會導致最終選擇。這個解決方案相當簡單(至少對於我的應用程序而言),並且有兩個組件(請原諒這個論壇不熟悉,我不確定代碼顯示不正確的原因) 。

1 - 註冊一個AWTListener來跟蹤由用戶

class MyChooser extends JFileChooser implements java.awt.AWTEventListener { 

    ... 
    MyChooser(){ 
     Toolkit.getDefaultToolkit().addAWTEventListener(this, 
     AWTEvent.MOUSE_EVENT_MASK + AWTEvent.KEY_EVENT_MASK); 
     ... 

    } 

    int lastEventId; 

    public void eventDispatched(AWTEvent e) { 
     lastEventId=e.getID(); 
    } 
} 

2所產生的最後一個事件類型的 - 覆蓋的JFileChooser的approveSelection()方法,並檢查是否批准請求是小鼠的結果事件(可能是由用戶單擊「打開」按鈕引起的)或由用戶按Enter鍵導致的鍵事件。 'lastEventId'變量提供對這些信息的訪問。我自己的批准選擇然後看起來如下:

public void approveSelection() { 
    File f=getSelectedFile(); 
    if (f.exists() && isTraversable(f) && lastEventId == 
     KeyEvent.KEY_PRESSED) { 
     setCurrentDirectory(f); 
     return; 
    } 
    super.approveSelection(); } 
+0

精美的作品。作爲一個鼠標 - 憎恨的默認功能真的很煩人,我擔心找到解決方案會很困難。 – 2016-02-24 20:16:33