views:

111

answers:

1

I am attempting to implmement smart autoscrolling on a JScrollPane containing a JTextPane. The JTextPane is used for logging my app in color. However I'm running into a wall trying to do smart autoscrolling. By smart autoscrolling I don't mean blindly autoscrolling every time something changes, I mean checking to see if your scrolled all the way down, then autoscroll. However no matter what I do it either always autoscrolls or doesn't at all

As a test script, here's the setup (the JFrame has been left out)

final JTextPane textPane = new JTextPane();
textPane.setEditable(false);
final JScrollPane contentPane = new JScrollPane(textPane);
contentPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

And here's the ugly auto add test loop

while (true)
    try {
        Thread.sleep(1000);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JScrollBar scrollBar = scroll;
                    boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum()));
                    System.out.println("Value: " + scroll.getValue()
                                    + " | Visible: " + scrollBar.getVisibleAmount()
                                    + " | Maximum: " + scrollBar.getMaximum()
                                    + " | Combined: " + (scrollBar.getValue() + scrollBar.getVisibleAmount())
                                    + " | Vis!=Max : " + (scrollBar.getVisibleAmount() != scrollBar.getMaximum())
                                    + " | Comb=Max: " + (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum())
                                    + " | Eval: " + preCheck);
                    StyledDocument doc = textPane.getStyledDocument();
                    doc.insertString(doc.getLength(), "FAGAHSIDFNJASDKFJSD\n", doc.getStyle(""));
                    if (!preCheck)
                            textPane.setCaretPosition(doc.getLength());
                } catch (BadLocationException ex) {
                            ex.printStackTrace();
                }
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }

Its not pretty, but it gets the job done.

Here's though the relevant check

 boolean preCheck = ((scrollBar.getVisibleAmount() != scrollBar.getMaximum()) && (scrollBar.getValue() + scrollBar.getVisibleAmount() == scrollBar.getMaximum()));
 if (preCheck)
     textPane.setCaretPosition(doc.getLength());

Thats the part thats been giving me trouble. There is first a check to see if the bar is visible but unusable (not enough text, making the bar the full length), then if the bottom of the bar is equal to the maximum. In theory, that should work. However nothing, including moving the check around, has gotten the results I would like.

Any suggestions?

NOT A DUPLICATE of this or this, as they are wanting it to always scroll, not just sometimes.

+1  A: 

Check out the code in this posting along with my comments in reply 3 and you might have a solution.

camickr