2009-05-03 10 views
5

Próbuję zmienić JList wewnątrz JScrollPane dynamicznie, przy użyciuBądź JScrollPane wyświetlania pasków przewijania, gdy zostanie zmieniony JList wewnątrz

myList.setListData(someArray); 

Po tym chciałbym oczekiwać JScrollPane pokazać przewijania, ile potrzeba, ale to nie robi” t się stało. Googlowanie problemu nie było zbyt pomocne. Próbowałem różnych kombinacji następujących metod, z niewielkim powodzeniem (zasadniczo wywiercenie poprzez api docs):

myScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 
myList.validate(); myScrollPane.validate(); 
myScrollPane.setPreferredSize(Dimension someDimension); 
myScrollPane.setViewportView(moduleList); 
myScrollPane.setLayout(...); 

Podczas korzystania z pierwszej metody pojawi się pasek przewijania, ale nie zostanie aktywowana przez zmianę modelu. Podłączyłem się również do PropertyChangeEvent i sprawdziłem, czy pożary JList i zdarzenie po zmianie modelu. Czego tu mi brakuje? Jakiej metody muszę użyć, aby to działało, lub jeszcze lepiej, która właściwość sprawiłaby, że to działało po wyjęciu z pudełka?

+1

Nie jestem pewien, czy to pomoże, ale upewnij się, że wywołanie metody setListData (...) występuje w wątku zdarzenia. Wszelkiego rodzaju paskudne rzeczy mogą się zdarzyć, jeśli zmutujesz obiekt interfejsu użytkownika w innym wątku. Również spojrzałeś na JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED? Nie jest do końca jasne, co masz na myśli przez "actived przez zmianę modelu". –

Odpowiedz

9

jeśli preferredSize jest ustawiony na JList, nawet jeśli (0, 0), a następnie JScrollPane nie działa - upewnić się, że jest wyłączony, setPreferredSize (null) w razie potrzeby

zobaczyć mrtextminer następująco

Rozwiązaniem tego problemu jest nie ustawienie preferowanej wielkości JList (usunięcie instrukcji ustawień). W Netbeans IDE 5.5.1, wyłączenie preferowanej wielkości JList można osiągnąć, klikając prawym przyciskiem myszy właściwość preferredSize w JList, a następnie wybierając "przywracanie wartości domyślnej".

Podsumowując, ustaw preferowaną wielkość tylko JScrollPane.Nie ustawiaj preferowanej wielkości listy JList.

+0

To faktycznie naprawiło długotrwały błąd w jednej z moich aplikacji. Dziękuję Ci. :) – Bombe

3

Właśnie napisałem małą przykładową aplikację, aby przetestować to zachowanie i działa po wyjęciu z pudełka. Po zmodyfikowaniu danych listy, pionowe i poziome paski przewijania są dodawane domyślnie do taczki.

public class Frametest { 

private JList list; 

public Frametest() { 
    JFrame f = new JFrame("Scrollable JList"); 
    f.setSize(200, 300); 
    JScrollPane jsp = new JScrollPane();   
    list = new JList(); 
    jsp.getViewport().add(list); 
    f.getContentPane().setLayout(new BorderLayout()); 
    f.getContentPane().add(jsp, BorderLayout.CENTER); 
    JButton button = new JButton("update"); 
    button.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent arg0) { 
      Object[] objects = new Object[20]; 
      for(int i=0; i<20; i++) { 
       objects[i] = "foo foo foo foo foo foo foo foo foo foo foo foo "+i; 
      } 
      list.setListData(objects); 
     } 
    }); 
    f.getContentPane().add(button, BorderLayout.SOUTH); 
    f.setVisible(true);  
} 

public static void main(String[] args) { 
    new Frametest(); 
}} 
+0

Podejrzewam, że może dodać dane PO pokazaniu się listy, ponieważ mówi o zmianie modelu ... – willcodejavaforfood

+0

Tak, działa w przykładzie! Po naciśnięciu przycisku aktualizacji (lista została już widoczna), model zostanie zmieniony, a paski przewijania zostaną dostosowane. –

+0

Tak, prawie robię dokładnie to, co zrobiłeś, ale twój kod działa dla mnie - będę bliżej przyjrzeć się temu, czego NIE robię ... Podejrzewam, że to może być coś z układem - dzięki! – VolkA

2

Czy próbowałeś wywołanie metody validate lub revalidate z JList podczas dokonywania zmian w danych liście?

myList.setListData(someArray); 
myList.revalidate(); 

Tak dla twojej informacji, po prostu zrobił szybki dochodzenia różnicy między validate i revalidate i wydaje się, że validate będzie układ do komponentu metoda została wezwana i jej dzieci, podczas gdy revalidate będzie przejdź do najwyższego rodzica, a następnie dokonaj zmian w układzie i tak dalej dla wszystkich jego dzieci.

Wywołanie revalidate na stronie myList spowoduje nie tylko sprawdzenie samej listy, ale także sprawdzenie poprawności również panelu przewijania, co wpłynie na widoczność paska przewijania w zależności od elementów rysowanych na liście.

+0

Tak, próbowałem obu, ale bez skutku ... – VolkA

1

To wygląda źle:

jsp.getViewport().add(list); 

Zamiast używać:

jsp.setViewportView(list); 

lub

new JScrollPane(list); 

a lista zostanie dodany poprawnie ScrollPane. Dodanie go w ten sposób informuje przewijaną stronę, aby go wysłuchał w celu wprowadzenia zmian.

1

jeśli trzeba jeszcze to spróbuj usunąć metody walidacji i jeśli masz setpreferredsize na liście usunąć go, że był jak kopalnia ale zawiedli

usunąłem

resultList.setPreferredSize(resultList.getPreferredSize()); 

i to done

Powiązane problemy