簡體   English   中英

改變JFileChooser行為:阻止在文件路徑JTextField中輸入“choose”

[英]altering JFileChooser behaviour : preventing “choose” on enter in file path JTextField

向Swing Pros致以問候,這是一個很好的(我希望)問題。

以下是我看到的任務要求和可能的解決方案。 我想有人有這樣的鐵桿經驗來分享一些關於這個的想法。

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

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

  1. 當用戶在文件名JTextField中按Enter鍵,並且該字段包含dir的路徑時,不要“選擇”目錄,而是切換到它。 是的,對話框配置為接受目錄,但我們只需要接受“打開”按鈕的點擊,並且(可能)雙擊文件列表表。

  2. 通過在文件名文本字段中輸入,阻止用戶選擇數據超過1GB的目錄/文件

以下是一些常規解決方案選項:

一個。 聆聽JFileChooser提供的基於屬性的更改(事后觸發哪個AFAICS,並且不會提供我們需要的控制程度)。

修改javax.swing.plaf.basic.BasicFileChooserUI(通過refrection,打破私有級封裝)並修改引用

private Action approveSelectionAction = new ApproveSelectionAction();

這樣我們的自定義操作就會對1和2進行額外檢查。這種方法與plaf包鏈接,如果在此UI類下面的某個類中以某種方式覆蓋此操作,則可能會失敗。

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

好吧,似乎公共JFileChooser API不足以實現這種行為,而其他兩個選項要么是深度魔術還是不可移植(長期),要么兩者兼而有之。

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

關於option2,您不需要使用反射來自定義accept Action。 您可以覆蓋approveSelection()方法。 就像是:

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

我最近遇到了同樣的要求,即在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(); } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM