开发者

Scroll JScrollPane to bottom

开发者 https://www.devze.com 2023-02-14 12:12 出处:网络
I need to scr开发者_C百科oll a JScrollPane to the bottom. The JScrollPane contains a JPanel, which contains a number of JLabel\'s.

I need to scr开发者_C百科oll a JScrollPane to the bottom. The JScrollPane contains a JPanel, which contains a number of JLabel's.

To scroll to the top, I just do:

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

but how do I scroll exactly to the very bottom? (Too far and it jitters)


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


After many hours of attempting to find an answer other than one using the scrollRectToVisible() method, I've succeeded. I've found that if you use the following code after you output text to the text area in the scrollpane, it will automatically focus on the bottom of the text area.

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

So, at least for me, my print method looks like this

public void printMessage(String 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());  
    }
});


Instead of setViewPosition(), I usually use scrollRectToVisible(), described in How to Use Scroll Panes. You could use the result of an appropriate label's getBounds() for the required Rectangle.

Addendum: @Matt notes in another answer, "If you use the following code after you output text to the text area in the scrollpane, it will automatically focus on the bottom of the text area."

In the particular case of a JTextComponent, also consider using the setUpdatePolicy() method of DefaultCaret to ALWAYS_UPDATE, illustrated here.


I adapted the code of Peter Saitz. This version leaves the scrollbar working after it has finished scrolling down.

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


None of the answers worked for me. For some reason my JScrollPane was not scrolling to the very bottom, even if I revalidated everything.

This is what worked for me:

SwingUtilities.invokeLater(() -> {
        JScrollBar bar = scroll.getVerticalScrollBar();
        bar.setValue(bar.getMaximum());
});


If your JScrollPane only contains a JTextArea then:

JScrollPane.getViewport().setViewPosition(new Point(0,JTextArea.getDocument().getLength()));


// Scroll to bottom of a JScrollPane containing a list of Strings.

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


I wanted to contribute my findings to this question, since I needed an answer for it today, and none of the solutions here worked for me, but I did finally find one that did. I had a JList object wrapped in a JScrollPane which I wanted to scroll to the last item after all elements had been added to a DefaultListModel. It essentially works like this:

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

I tried all of the solutions listed here but none seemed to have any effect. I found this one while experimenting, and it works perfectly. Thought I'd leave it here in the case it might help someone else.


ScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue( vertical.getMaximum() - 1 );

just set value to: vertical.getMaximum() - 1


I have tried several method. Some use bar.setValue(bar.getMaximum()), but the maximum is always 100 while the range of bar will be much more than 100. Some use textArea, but it is not suitable for that there is only a JTable in the JScrollPane. And I thing about a method, maybe stupid but effective.

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


If you look at the JTextArea documentation

public void select(int selectionStart, int selectionEnd)

Selects the text between the specified start and end positions. This method sets the start and end positions of the selected text, enforcing the restriction that the start position must be greater than or equal to zero. The end position must be greater than or equal to the start position, and less than or equal to the length of the text component's text.

If the caller supplies values that are inconsistent or out of bounds, the method enforces these constraints silently, and without failure. Specifically, if the start position or end position is greater than the length of the text, it is reset to equal the text length. If the start position is less than zero, it is reset to zero, and if the end position is less than the start position, it is reset to the start position.

So the simple solution is jTextArea.select(Integer.MAX_VALUE, 0); and let Java sort it out!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号