2010-01-25 26 views
13

Mam następny kod:JScrollPane i JList Autoprzewijanie

listModel = new DefaultListModel(); 
    listModel.addElement(dateFormat.format(new Date()) + ": Msg1"); 
    messageList = new JList(listModel); 
    messageList.setLayoutOrientation(JList.VERTICAL); 

    messageScrollList = new JScrollPane(messageList); 
    messageScrollList.setPreferredSize(new Dimension(500, 200)); 

    messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

przewija auto w dół. Ale jeśli spróbuję przewinąć do tyłu, aby ponownie przeczytać wiadomość, zmusza przewijanie w dół. Jak mogę to naprawić?

Odpowiedz

10

Dodając nową wiadomość, wywołać scrollRectToVisible() na JList użyciem Rectangle o takich samych wymiarach jak okienkiem wiadomości preferowanej wielkości. Biorąc pod uwagę orientację pionową, może być dogodne, aby preferowany rozmiar wielowtykowej wysokości panelu wiadomości stanowił całkowitą liczbę. Zobacz także: How to Use Scroll Panes.

Dodatek: Ta fascynująca dyskusja na temat Text Area Scrolling może być również pomocna.

-1

Myślę, że to, co chcesz zrobić, to przewiń w dół, gdy dodasz coś do swojej listy wiadomości, a nie na dostosowanie. Więc twój kod mógłby wyglądać następująco:

Adjustable sb = messageScrollList.getVerticalScrollBar() 
boolean onBottom = sb.getValue() == sb.getMaximum(); 
// 
// add your message to the JList. 
// 
if(onBottom) sb.setValue(sb.getMaximum()); 

W przeciwnym razie trzeba by stwierdzić, czy korekta była spowodowana zmianą modelu, lub za pomocą myszy, a pominie docs API nie jestem pewien, czy istnieje sposób, aby to zrobić łatwo. Chociaż możesz sprawdzić, czy AdjustmentEvent.getAdjustmentType() zwraca różne wartości w tych przypadkach, jeśli to prawda, możesz po prostu mieć instrukcję if w anonimowej klasie wewnętrznej.

Inną rzeczą, którą można wypróbować, jest ustawienie zmiennej boolowskiej, która zostanie ustawiona po dodaniu czegoś do listy. Następnie w programie obsługi sprawdzasz, czy zmienna jest ustawiona. Jeśli tak, to wykonasz regulację (i zresetujesz zmienną), w przeciwnym razie zignorujesz ją. W ten sposób do listy zostanie dodany tylko jeden przewijany element.

+0

Typ dopasowania jest taki sam w obu przypadkach. Próbowałem to przewinąć w dół, jeśli dodano wiadomość. Ale jeśli to zrobię, ostatnia dodana wiadomość nie będzie widoczna. Nie przewraca się w dół. Jak mogę to rozwiązać? – dododedodonl

+0

Hmm ... Cóż, jedną rzeczą, którą możesz zrobić, to mieć zmienną boolowską, która zostanie ustawiona, gdy dodasz coś do listy. Następnie w programie obsługi sprawdzasz, czy zmienna jest ustawiona. Jeśli tak, to wykonasz regulację (i zresetujesz zmienną), w przeciwnym razie zignorujesz ją. W ten sposób do listy zostanie dodany tylko jeden przewijany element. –

1
this.list = blah blah... 
this.list.setSelectedValue(whatever); 
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp 
this.list.ensureIndexIsVisible(this.list.getSelectedIndex()); 
1

Znalazłem to naprawdę przydatne: http://forums.sun.com/thread.jspa?threadID=623669 (post przez 'inopia')
działa idealnie

Jak sam mówi: „Problem polega na tym, że może stać się nieco trudne do znalezienia zdarzenie uruchamiane po zaktualizowaniu zarówno ListModel, JList, jak i JScrollPane. "

+0

Link jest martwy. Czy możesz to odświeżyć? –

0

Aby Autoprzewijanie używam bardzo prostą koncepcję zmiennej statycznej i list.makeVisible (int index)

public class autoScrollExample 
    { 
    static int index=0; 
    private void someFunction() 
    /* 
    * 
    */ 
    list1.add("element1"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 

    private void someOtherFunction() 
    /* 
    * 
    */ 
    list1.add("element2"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 


    } 
1

@question Enquirer. Proszę zmienić kod z

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

do

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getValue()); 
     } 
    }); 

To zmiana getMaximum() do getValue() Wtedy to działa zgodnie z wymaganiami. getMaximum() przejmuje pokrętło do maksymalnej wartości; podczas gdy getValue() zabiera go wszędzie tam, gdzie wydarzenie się dzieje.

można uniknąć stosując ten kawałek kodu w ogóle, jeśli umieścić jedną linię

messageScrollList.setViewportView(messageList); 

podobny add(component) dla JList i dostaje swoją wrodzoną zachowanie.