2010-11-20 5 views
5

Pozdrowienia dla Swing Pros, oto dobre (mam nadzieję) pytanie dla ciebie.Zmienianie zachowania JFileChooser: zapobieganie "wybrać" przy wejściu w ścieżce pliku JTextField

Poniżej przedstawiamy wymagania zadania i możliwe rozwiązania, które widzę. Chciałbym, aby ktoś, kto miał takie hardcorowe doświadczenie, podzielił się z nami swoimi przemyśleniami.

To nie wymaga kodowania lub coś podobnego, tylko trzeba ogólne porady, co do których podejście jest bardziej niezawodny w związku z faktem, że trzeba pracować z prywatnych symboli, które znajdują się w sun.swing i/lub pakiety javax.swing.plaf.

Zadanie polega na zmodyfikowaniu/zmianie zachowania JFileChooser (właściwie tylko trochę).

  1. gdy użytkownik naciśnie klawisz Enter w nazwie pliku JTextField, a pole zawiera ścieżkę do katalogu, nie „wybierz” dir, ale zamiast niego przełączyć. Tak, okno dialogowe jest skonfigurowane do akceptowania katalogów, ale musimy zaakceptować tylko kliknięcia przycisku "Otwórz" i (prawdopodobnie) dwukrotne kliknięcie w tabeli listy plików.

  2. uniemożliwić użytkownikowi wybranie dir/pliku z więcej niż 1GB danych poprzez uderzanie wpisać w polu tekstowym Nazwa pliku

Here're Kilka opcji ogólnych rozwiązanie:

a. posłuchaj zmian opartych na właściwościach, które zapewnia JFileChooser (które AFAICS są wywoływane po fakcie i nie zapewniają wymaganego stopnia kontroli).

b. majstrować przy javax.swing.plaf.basic.BasicFileChooserUI (przez refrection, łamiąc enkapsulacji prywatne szczebla) i zmienić odniesienie do

private Action approveSelectionAction = new ApproveSelectionAction(); 

aby nasze działanie ma zwyczaj dodatkowe kontrole na 1 i 2. Niniejsza podejście do linków z pakietem plaf i może się nie powieść, jeśli ta akcja zostanie w jakiś sposób nadpisana w jakiejś klasie poniżej tej klasy interfejsu użytkownika.

c. przechodzimy przez hierarchię komponentów JFileChooser, znajdujemy JTextField (który najwyraźniej powinien pojawić się tylko raz w drzewie komponentów), dekorujemy wszystkie detektory działania wiszące na tym JTextField za pomocą naszych niestandardowych sprawdzeń. Moja sesja debugowania pokazuje, że JTextField jest anonimową podklasą JTextField żyjącą w sun.swing.FilePane. To podejście wydaje się być bardziej przyjazne dla OO, ale jest szansa, że ​​w przypadku niektórych systemów operacyjnych to pole tekstowe jest nieobecne, lub jakiś inny JTextField jest również obecny w hierarchii.

Cóż, wydaje się, że publiczny interfejs JFileChooser nie byłby wystarczający do osiągnięcia tego zachowania, podczas gdy pozostałe dwie opcje to albo głęboka magia, albo nieprzewidywalny (długoterminowy), albo nawet oba.

Pytanie brzmi: jakie podejście wybrałbyś i dlaczego?

Odpowiedz

5

Odnośnie opcji 2, nie trzeba używać odbicia, aby dostosować Akcję akceptacji. Możesz po prostu zastąpić metodę approveSelection(). Coś takiego:

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

O, kurwa, sprawdzę to i opowiem o swoich odkryciach. –

+0

No tak, byłem w stanie przechwycić i rozbroić zdarzenie selekcji zatwierdzenia przez NIE wywoływanie super.approveSelection() w niektórych przypadkach, które powinny zostać uznane za nieważne. To było całkiem fajne rozwiązanie, dzięki jeszcze raz. –

3

Niedawno spotkałem się z tym samym wymaganiem, tj., naciśnięcie klawisza Enter w JTextField programu JFileChooser powinno spowodować, że wyświetlone okno dialogowe będzie przechodzić przez katalog zamiast powracać z okna dialogowego. Tylko kliknięcie przycisku Otwórz powinno spowodować ostateczny wybór.

Rozwiązanie było dość proste (przynajmniej dla mojej aplikacji) i zawiera dwa komponenty (przepraszam za formatowanie, jestem nowy na tym forum i nie jestem pewien, dlaczego kod nie wyświetla się poprawnie) .

1 - Sugestie AWTListener śledzić ostatniego typu zdarzeń generowanych przez użytkownika

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 - zastąpić metodę approveSelection() z JFileChooser i sprawdzić, czy żądanie zatwierdzenia wynika z myszką zdarzenie (prawdopodobnie spowodowane kliknięciem przycisku Otwórz) lub zdarzenie kluczowe spowodowane naciśnięciem klawisza Enter. Zmienna "lastEventId" zapewnia dostęp do tych informacji. Moje własne zatwierdzenie wyboru wygląda następująco:

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

Działa pięknie. Jako mysz-ophobic, domyślna funkcja naprawdę mnie denerwowała i obawiałam się, że znalezienie rozwiązania będzie trudne. –