Domanda

Ho il codice successivo:

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

Si scorre auto verso il basso. Ma, se provo a scorrere indietro fino a ri-leggere un messaggio, costringe uno scorrimento verso il basso. Come posso risolvere questo problema?

È stato utile?

Soluzione

Quando si aggiunge un nuovo messaggio, richiamare scrollRectToVisible() sulla JList utilizzando un Rectangle vista le stesse dimensioni dimensione preferita del riquadro dei messaggi. Dato un orientamento verticale, può essere conveniente per rendere la dimensione preferita del JScrollPane 's JViewport un multiplo intero della altezza del riquadro dei messaggi. Vedi anche: Come usare Scroll Panes .

Addendum: Questo interessante discussione di Testo Area di scorrimento può essere utile, anche.

Altri suggerimenti

Ho trovato questo veramente utile: http://forums.sun.com/thread.jspa?threadID=623669 (messaggio di 'inopia')
Funziona perfettamente

Come egli dice: "Il problema qui è che può diventare un po 'difficile trovare un evento che spara dopo sia il ListModel, JList e JScrollPane sono stati aggiornati."

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

@question Enquirer. Si prega di modificare il codice da

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

a

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

Questo è il cambiamento getMaximum() per getValue() allora funziona come richiesto. getMaximum() prende lo scroller al massimo; mentre getValue() prende ovunque evento si verifica.

È possibile evitare l'uso di questo pezzo di codice del tutto, se si mette una riga

messageScrollList.setViewportView(messageList);

Questo funziona come add(component) per JList e ottiene il suo comportamento intrinseco.

Per lo scorrimento automatico Sto usando un semplice concetto di variabile statica e 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++);
     /*
     *
     */


    }

Ho usato JScrollPane con JTextArea. Ho evitato la forza di scorrimento verso il basso per lo scorrimento solo quando il valore JScrollBar max modificato:

        JScrollPane scrollPane = new JScrollPane(jTextArea);

        verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
        scrollPane.getVerticalScrollBar().addAdjustmentListener(
                e -> {
                    if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
                        return;
                    e.getAdjustable().setValue(e.getAdjustable().getMaximum());
                    verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
                });

suppongo, non c'è soluzione migliore per filtrare gli eventi senza variabili aggiuntive, e gradirebbe se qualcuno post-it.

Credo che ciò che si vuole fare è avere lo scorrere verso il basso quando si aggiunge roba al vostro messageList, piuttosto che sulla regolazione. Quindi, il codice potrebbe essere la seguente:

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

In caso contrario si avrebbe bisogno di dire se l'adeguamento è stato causato da un cambiamento del modello, o con il mouse, e guardando attraverso la documentazione API non sono sicuro se c'è un modo per farlo facilmente. Anche se si potrebbe vedere se il AdjustmentEvent.getAdjustmentType() restituisce valori diversi in questi casi, se questo è vero allora si potrebbe semplicemente avere un'istruzione if nella classe interna anonima.

Un'altra cosa che si potrebbe provare sarebbe quello di avere un qualche variabile booleana che viene impostata quando si aggiunge qualcosa alla lista. Poi, nel gestore di controllare per vedere se è impostata la variabile. Se è così, si fa la regolazione (e disinserire la variabile) in caso contrario, lo si ignora. In questo modo, non ci sarà un solo scorrere verso il basso per voce di essere aggiunto alla lista.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top