2010-01-25 12 views
13

Ich habe den nächsten Code bekam:JScrollPane und JList Autoscroll

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()); 
     } 
    }); 

Es Auto nach unten scrollt. Wenn ich jedoch versuche, zurückzuscrollen, um eine Nachricht erneut zu lesen, wird eine Bildlaufoperation erzwungen. Wie kann ich das beheben?

Antwort

10

Wenn eine neue Nachricht hinzugefügt, rufen scrollRectToVisible() auf den JList ein Rectangle mit den gleichen Abmessungen wie Ihre Meldungsfenster bevorzugte Größe verwendet wird. Bei einer vertikalen Ausrichtung, kann es zweckmäßig sein, die bevorzugte Größe der JScrollPane ‚s JViewport einem ganzzahligen Vielfachen der Höhe des Nachrichtenbereich zu machen. Siehe auch: How to Use Scroll Panes.

Nachtrag: Die überzeugende Diskussion von Text Area Scrolling kann hilfreich sein, auch.

-1

Ich denke, was Sie tun möchten, ist es müssen nach unten scrollen, wenn Sie Sachen zu Ihrem Message hinzufügen, eher dann auf Einstellung. So könnte Ihr Code wie folgt aussehen:

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

Sonst würden Sie sagen müssen, wenn die Einstellung durch eine Modellwechsel verursacht wurde, oder von der Maus, und auf der Suche durch die API-Dokumentation Ich bin nicht sicher, ob es eine ist Möglichkeit, das leicht zu machen. Obwohl könnte man jene Fälle sehen, ob die AdjustmentEvent.getAdjustmentType() in unterschiedlichen Werten zurückkehrt, wenn das wahr ist, dann können Sie nur eine if-Anweisung in Ihrer anonyme innere Klasse.

Eine andere Sache, die Sie würden versuchen könnte, eine boolesche Variable irgendwo zu haben, die eingestellt wird, wenn Sie etwas zu der Liste hinzufügen. Dann prüfen Sie in Ihrem Handler, ob die Variable gesetzt ist. Wenn dies der Fall ist, führen Sie die Anpassung durch (und deaktivieren die Variable), andernfalls ignorieren Sie sie. Auf diese Weise wird nur ein Scroll-Down pro Element zur Liste hinzugefügt.

+0

Der Einstellungstyp ist in beiden Fällen identisch. Ich habe dies versucht, um nach unten zu scrollen, wenn eine Nachricht hinzugefügt wird. Aber wenn ich das tue, ist die letzte hinzugefügte Nachricht nicht sichtbar. Es scrollt nicht genug nach unten. Wie kann ich das lösen? – dododedodonl

+0

Hmm ... Nun, eine Sache, die Sie tun könnten, wäre, eine boolesche Variable irgendwo zu haben, die gesetzt wird, wenn Sie etwas zur Liste hinzufügen. Dann prüfen Sie in Ihrem Handler, ob die Variable gesetzt ist. Wenn dies der Fall ist, führen Sie die Anpassung durch (und deaktivieren die Variable), andernfalls ignorieren Sie sie. Auf diese Weise wird nur ein Scroll-Down pro Element zur Liste hinzugefügt. –

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

fand ich das wirklich nützlich: http://forums.sun.com/thread.jspa?threadID=623669 (Beitrag von ‚inopia‘)
Es perfekt

arbeitet Wie er sagt: „Das Problem hier ist, dass es ein bisschen schwierig werden kann zu finden ein Ereignis, das ausgelöst wird, nachdem sowohl das Listmodel, JList und JScrollPane wurden aktualisiert.“

+0

Link ist tot. Kannst du es auffrischen? –

0

Um Autoscroll Ich bin mit einem sehr einfachen Konzept der statischen Variablen und 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. Bitte ändern Sie den Code aus

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

zu

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

Das heißt Veränderung getMaximum()-getValue() Dann funktioniert es wie gewünscht. nimmt den Farbwechsler bis zum Maximum; während getValue() dauert es, wo immer es passiert.

Sie können mit diesem Stück Code ganz vermeiden, wenn Sie

messageScrollList.setViewportView(messageList); 

eine Zeile setzen, die wie add(component) für JList arbeitet und bekommt seine inhärente Verhalten.

Verwandte Themen