Faites défiler JScrollPane vers le bas

Je dois faire défiler un JScrollPane vers le bas. JScrollPane contient un JPanel, qui contient un certain nombre de JLabel.

Pour faire défiler vers le haut, je fais juste:

scrollPane.getViewport().setViewPosition(new Point(0,0)); 

mais comment faire défiler exactement tout en bas? (Trop loin et ça tremble)

 JScrollBar vertical = scrollPane.getVerticalScrollBar(); vertical.setValue( vertical.getMaximum() ); 

Après plusieurs heures de tentatives pour trouver une réponse autre que celle utilisant la méthode scrollRectToVisible (), j’ai réussi. J’ai constaté que si vous utilisez le code suivant après avoir affiché du texte dans la zone de texte du panneau de défilement, celui-ci se focalise automatiquement sur le bas de la zone de texte.

 textArea.setCaretPosition(textArea.getDocument().getLength()); 

Donc, au moins pour moi, ma méthode d’impression ressemble à ceci

 public void printMessage(Ssortingng message) { textArea.append(message + endL); textArea.setCaretPosition(textArea.getDocument().getLength()); } 
 scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { e.getAdjustable().setValue(e.getAdjustable().getMaximum()); } }); 

Au lieu de setViewPosition() , j’utilise généralement scrollRectToVisible() , décrit dans Comment utiliser les volets de défilement . Vous pouvez utiliser le résultat de getBounds() d’une étiquette appropriée pour le Rectangle requirejs.

Addendum: @Matt note dans une autre réponse : “Si vous utilisez le code suivant après avoir sorti du texte dans la zone de texte du panneau de défilement, il se concentrera automatiquement sur le bas de la zone de texte.”

Dans le cas particulier d’un JTextComponent , envisagez également d’utiliser la méthode setUpdatePolicy() de DefaultCaret à ALWAYS_UPDATE , illustrée ici .

J’ai adapté le code de Peter Saitz . Cette version laisse la barre de défilement fonctionner une fois le défilement terminé.

 private void scrollToBottom(JScrollPane scrollPane) { JScrollBar verticalBar = scrollPane.getVerticalScrollBar(); AdjustmentListener downScroller = new AdjustmentListener() { @Override public void adjustmentValueChanged(AdjustmentEvent e) { Adjustable adjustable = e.getAdjustable(); adjustable.setValue(adjustable.getMaximum()); verticalBar.removeAdjustmentListener(this); } }; verticalBar.addAdjustmentListener(downScroller); } 

Si votre JScrollPane ne contient qu’un JTextArea, alors:

 JScrollPane.getViewport().setViewPosition(new Point(0,JTextArea.getDocument().getLength())); 
 // Scroll to bottom of a JScrollPane containing a list of Ssortingngs. JScrollPane scrollPane; DefaultListModel listModel; JList list; listModel = new DefaultListModel(); list = new JList(listModel); list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); list.setLayoutOrientation(JList.VERTICAL); list.setVisibleRowCount(-1); // -1 = display max items in space available scrollPane = new JScrollPane(list); scrollPane.setPreferredSize(new Dimension(200, 50)); // Append text ensortinges onto the text scroll pane. listModel.addElement("text entry one"); listModel.addElement("text entry two"); listModel.addElement("text entry three"); listModel.addElement("text entry four"); // Get the index of the last entry appended onto the list, then // select it, and scroll to ensure it is visible in the vewiport. int lastNdx = listModel.getSize() - 1; list.setSelectedIndex(lastNdx); list.ensureIndexIsVisible(lastNdx); JPanel panel = new JPanel(); panel.add(scrollPane); 

J’ai essayé plusieurs méthodes. Certains utilisent bar.setValue(bar.getMaximum()) , mais le maximum est toujours 100 alors que l’intervalle de barre sera beaucoup plus que 100. Certains utilisent textArea, mais cela ne convient pas car il n’y a qu’une JTable dans JScrollPane . Et je pense à une méthode, peut-être stupide mais efficace.

 JScrollBar bar=jsp.getVerticalScrollBar(); int x=bar.getValue(); for(int i=100;i<2000000000;i+=100) { bar.setValue(i); if(x==bar.getValue()) break; x=bar.getValue(); } 

Je voulais apporter mes découvertes à cette question, car j’avais besoin d’une réponse aujourd’hui, et aucune des solutions proposées ici n’a fonctionné pour moi, mais j’ai finalement trouvé celle qui l’a fait. J’avais un object JList enveloppé dans un JScrollPane que je voulais faire défiler jusqu’au dernier élément après que tous les éléments avaient été ajoutés à un DefaultListModel. Cela fonctionne essentiellement comme ceci:

 JList list = new JList(); DefaultListModel listModel = new DefaultListModel(); JScrollPane listScroller = new JScrollPane(list); public void populateList() { //populate the JList with desired items... list.ensureIndexIsVisible(listModel.indexOf(listModel.lastElement())); } 

J’ai essayé toutes les solutions listées ici mais aucune ne semblait avoir d’effet. J’ai trouvé celui-ci en expérimentant, et cela fonctionne parfaitement. Je pensais le laisser ici dans le cas où cela pourrait aider quelqu’un d’autre.

Si vous regardez la documentation JTextArea

public void select (int selectionStart, int selectionEnd)

Sélectionne le texte entre les positions de début et de fin spécifiées. Cette méthode définit les positions de début et de fin du texte sélectionné, imposant la ressortingction selon laquelle la position de départ doit être supérieure ou égale à zéro. La position finale doit être supérieure ou égale à la position de départ et inférieure ou égale à la longueur du texte du composant texte.

Si l’appelant fournit des valeurs incohérentes ou hors limites, la méthode applique ces contraintes de manière silencieuse et sans échec. Plus précisément, si la position de départ ou la position finale est supérieure à la longueur du texte, elle est réinitialisée pour correspondre à la longueur du texte. Si la position de départ est inférieure à zéro, elle est remise à zéro et si la position finale est inférieure à la position de départ, elle est réinitialisée à la position de départ.

La solution simple est donc jTextArea.select (Integer.MAX_VALUE, 0); et laissez Java régler le problème!