2 Replies Latest reply: Jun 26, 2009 2:20 PM by 800581 RSS

    Stop JScrollPane Scrolling If Knob Is Not At Bottom

    800581
      My problem appears quite simple. I have a non-editable JTextArea in a JScrollPane. When text is added to the text area I want the vertical JScrollBar to autoscroll only if the knob is at the bottom of the track. If the user has scrolled up (e.g. to see a previous message) then the scroll bar should respect that and not change the position of the knob until the user moves the knob back to the bottom of the track. I've done quite a bit of searching for an answer and the following is the only one I've found that works, but I don't want to use it unless I absolutely have to because it just seems so wrong:
                AbstractDocument doc = (AbstractDocument) messageArea.getDocument();
                 DocumentListener[] listeners = doc.getDocumentListeners();
                 for (DocumentListener documentListener : listeners) {
                    if (documentListener.getClass().getName().equals("javax.swing.text.DefaultCaret$Handler")) {
                       doc.removeDocumentListener(documentListener);
                    }
                 }}
      Can someone please put me out of my misery and tell me the proper way to stop my JScrollBar from scrolling if the knob is at the bottom of the track? I would greatly appreciate it. Thanks.
        • 1. Re: Stop JScrollPane Scrolling If Knob Is Not At Bottom
          DarrylBurke
          camickr's [_Text Area Scrolling_|http://tips4java.wordpress.com/2008/10/22/text-area-scrolling/] may point you in the right direction.

          db

          edit Yup, with a little tweaking
          import java.awt.BorderLayout;
          import java.awt.event.ActionEvent;
          import java.awt.event.ActionListener;
          import java.awt.event.AdjustmentEvent;
          import java.awt.event.AdjustmentListener;
          import javax.swing.*;
          import javax.swing.text.DefaultCaret;
          
          public class ScrollControl {
          
             JTextArea textArea;
             JScrollBar scrollBar;
             DefaultCaret caret;
             BoundedRangeModel model;
          
             public static void main(String[] args) {
                SwingUtilities.invokeLater(new Runnable() {
          
                   @Override
                   public void run() {
                      new ScrollControl().makeUI();
                   }
                });
             }
          
             public void makeUI() {
                textArea = new JTextArea(20, 30);
                textArea.setWrapStyleWord(true);
                textArea.setLineWrap(true);
                caret = (DefaultCaret) textArea.getCaret();
                
                JScrollPane scrollPane = new JScrollPane(textArea);
                scrollBar = scrollPane.getVerticalScrollBar();
                model = scrollBar.getModel();
                scrollBar.addAdjustmentListener(new AdjustmentListener() {
          
                   public void adjustmentValueChanged(AdjustmentEvent e) {
                      if (model.getValue() == model.getMaximum() - model.getExtent()) {
                         caret.setDot(textArea.getText().length());
                         caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
                      } else {
                         caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
                      }
                   }
                });
          
                JButton button = new JButton("Click");
                button.addActionListener(new ActionListener() {
          
                   public void actionPerformed(ActionEvent e) {
                      for (int i = 0; i < 10; i++) {
                         textArea.append("The quick brown fox jumps over the lazy dog. ");
                      }
                   }
                });
                
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setSize(400, 400);
                frame.add(scrollPane, BorderLayout.CENTER);
                frame.add(button, BorderLayout.SOUTH);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
             }
          }
          Edited by: DarrylBurke
          • 2. Re: Stop JScrollPane Scrolling If Knob Is Not At Bottom
            800581
            Perfect. Thanks :)