[英]altering JFileChooser behaviour : preventing “choose” on enter in file path JTextField
向Swing Pros致以問候,這是一個很好的(我希望)問題。
以下是我看到的任務要求和可能的解決方案。 我想有人有這樣的鐵桿經驗來分享一些關於這個的想法。
這不需要編碼或類似的東西,我只需要一般性的建議 ,關於我需要使用駐留在sun.swing和/或javax.swing.plaf包中的私有符號的事實,哪種方法更可靠。
任務是修改/改變JFileChooser行為(實際上只是一點點)。
當用戶在文件名JTextField中按Enter鍵,並且該字段包含dir的路徑時,不要“選擇”目錄,而是切換到它。 是的,對話框配置為接受目錄,但我們只需要接受“打開”按鈕的點擊,並且(可能)雙擊文件列表表。
通過在文件名文本字段中輸入,阻止用戶選擇數據超過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.