Results 1 to 9 of 9
  1. #1
    Shadow is offline Member
    Join Date
    Oct 2008
    Posts
    5
    Rep Power
    0

    Default Getting JScrollPane to stop auto-scrolling

    I have a JScrollPane (named scrollPane), 2 JPanels (named panel1, panel2), and a JTextArea (named textArea). ScrollPane has panel1 in it while panel1 has a gridBagLayout and it has panel2 and the textArea in it with panel2 being north of textArea. Panel1 is bigger than the screen size so you need to scroll to be able to see all of panel2 and textarea since they fill their constraints.

    Now when text is appended to the textarea, no matter where I am currently scrolled with the scrollPane, it scrolls to where the text is added. I have tried the autoscrolls method but that does not work. Setting the caret position of the textArea will not work for how the components are ordered since if I am currently scrolled to panel2, I don't want it to move off of panel2 when text is appened.

    Does anyone know of some ways in which to stop the scrollPane from autoscrolling when text is appended to the textArea?

  2. #2
    Shadow is offline Member
    Join Date
    Oct 2008
    Posts
    5
    Rep Power
    0

    Default

    After messing around with it for a couple days, I still haven't found a solution (aside from writing my own ScrollPane class). If anyone has any suggestions, please let me know. Thanks.

  3. #3
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    To get better help sooner, post a SSCCE (see SSCCE : Java Glossary ) that clearly demonstrates your problem.

    db

  4. #4
    Shadow is offline Member
    Join Date
    Oct 2008
    Posts
    5
    Rep Power
    0

    Default

    Java Code:
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    
    public class Example{
    	private JTextArea _textArea;
    
    	public Example(){
    		//creates a basic frame
    		JFrame frame = new JFrame();
    		frame.setSize(510, 335);
    		frame.getContentPane().setBackground(Color.BLACK);
    		frame.setFocusable(false);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    		frame.setResizable(false);
    		frame.setLayout(new GridBagLayout());
    
    		//a panel that will hold panel2 and textAreaPanel
    		JPanel panel1 = new JPanel();
    		panel1.setBackground(Color.BLACK);
    		panel1.setPreferredSize(new Dimension(510, 1000));
    		panel1.setSize(400, 1000);
    
    		//a panel that will hold the button
    		JPanel panel2 = new JPanel();
    		panel2.setPreferredSize(new Dimension(510, 565));
    		panel2.setSize(510, 565);
    
    		//a panel that will hold the textArea
    		JPanel textAreaPanel = new JPanel();
    		textAreaPanel.setBackground(Color.BLACK);
    		textAreaPanel.setLayout(new GridBagLayout());
    		textAreaPanel.setPreferredSize(new Dimension(510, 400));
    		textAreaPanel.setSize(new Dimension(510, 400));
    
    		//a button that will append text to the textArea
    		JButton button = new JButton("Press for effect");
    		button.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent action) {
    				Example.this.appendToTextArea();
    			}
    		});
    		panel2.add(button);
    
    		//a scrollpane that will hold panel1
    		JScrollPane scrollPane = new JScrollPane(panel1);
    		JScrollBar scrollBar = scrollPane.getVerticalScrollBar();
    		scrollBar.setUnitIncrement(100);
    
    		_textArea = new JTextArea();
    		_textArea.setForeground(Color.RED);
    
    		GridBagConstraints c = new GridBagConstraints();
    
    		c = new GridBagConstraints();
    		c.gridx = 0;
    		c.gridy = 0;
    		c.weightx = 1.0;
    		c.weighty = 1.0;
    		c.fill = GridBagConstraints.BOTH;
    		panel1.add(panel2, c);
    		frame.add(scrollPane, c);
    		textAreaPanel.add(_textArea);
    
    		c.weighty = 0;
    		c.gridy = 1;
    		panel1.add(textAreaPanel, c);
    
    		frame.validate();
    	}
    
    	//Appends text to the text area whenever the button is pressed
    	public void appendToTextArea(){
    		_textArea.append("STOP AUTO-SCROLLING!!");
    	}
    
    	public static void main(String args[]){
    		new Example();
    	}
    }
    When the button is pressed, I don't want the scrollPane to auto-scroll to where the text is appended. I want it to stay where it is currently scrolled. Anyone have any ideas?

  5. #5
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    A slight flicker, but maybe it'll be acceptable.
    Java Code:
       public void appendToTextArea() {
          final Rectangle rect = panel1.getVisibleRect();
          _textArea.append("STOP AUTO-SCROLLING!!");
          SwingUtilities.invokeLater(new Runnable() {
    
             public void run() {
                panel1.scrollRectToVisible(rect);
             }
          });
       }
    If that doesn't do it, post back and we'll take another look.

    db

    edit panel1 declared as an instance field instead of local to the constructor.

  6. #6
    Shadow is offline Member
    Join Date
    Oct 2008
    Posts
    5
    Rep Power
    0

    Default

    Thanks for the help man but the scrollPane jumping around is too noticible. In my actual code, instead of a button I have lots of options for the user to pick so text is pretty much constantly being added so the scrollPane jumping around would be a problem.

    I was messing around with the scrollBars AdjustmentListener but I can't think of a way to differantiate between manual scoll and an appending scroll. So I don't know if thats the right direction to go.


    If you have any more ideas then I'm all ears.

  7. #7
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    This messes up keyboard navigation, and the caret doesn't move while typing, so all text is inserted to the left. It's a solution only if the JTextArea is setEditable(false), but no guarantees. Adopt at your own risk.

    Keep the appendToTextArea() as posted by you, not the modified version I posted earlier.
    Java Code:
          _textArea = new JTextArea();
          _textArea.setForeground(Color.RED);
          _textArea.setEditable(false);
          AbstractDocument doc = (AbstractDocument) _textArea.getDocument();
          DocumentListener[] listeners = doc.getDocumentListeners();
          for (DocumentListener documentListener : listeners) {
             if (documentListener.getClass().getName().equals("javax.swing.text.DefaultCaret$Handler")) {
                doc.removeDocumentListener(documentListener);
             }
          }
    This removes the DocumentListener responsible for responding to changes in the caret position, and effectively prevents the autoscrolling.

    Post back if this too is not suitable... but the only other approach I can see is by customizing the Caret, which wouldn't be easy (may not be possible) as there's a lot of package-private stuff there.

    db
    Last edited by DarrylBurke; 10-21-2008 at 07:13 PM.

  8. #8
    Shadow is offline Member
    Join Date
    Oct 2008
    Posts
    5
    Rep Power
    0

    Default

    Aha, I see what you did there, pretty clever man. I don't have to worry about user input for the textAreas so it works exactly how I want it to. Thnx bro, I appreciate the help.

  9. #9
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,188
    Rep Power
    19

    Default

    Hold on. There was a discussion just now on another forum
    Swing - Adjusting ScrollBar of JScrollPane
    which gave me a much cleaner approach than removing the listener.
    Java Code:
          _textArea = new JTextArea();
          _textArea.setForeground(Color.RED);
          _textArea.setEditable(false);
          DefaultCaret caret = (DefaultCaret) _textArea.getCaret();
          caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
    db

    edit It has the same effect on text typing as removing the listener, but isn't hackish: it uses the public API and can be guaranteed against future updates / versions. The weakness of the 'solution' I posted earlier is that it relies on the class name of an inner class. not likely to change, but no guarantees as I said.
    Last edited by DarrylBurke; 10-21-2008 at 08:58 PM.

Similar Threads

  1. MouseMotionListener 'scrolling'
    By Thez in forum Java 2D
    Replies: 3
    Last Post: 03-12-2009, 11:48 AM
  2. how to stop a thread
    By willemjav in forum Advanced Java
    Replies: 19
    Last Post: 09-10-2008, 07:11 AM
  3. Auto-complete/Auto-fix for custom statement
    By dark_cybernetics in forum Eclipse
    Replies: 0
    Last Post: 08-19-2008, 11:19 AM
  4. AWT Table Scrolling
    By albert_kam in forum AWT / Swing
    Replies: 0
    Last Post: 01-03-2008, 11:37 AM
  5. JScrollPane not scrolling
    By Riftwalker in forum Advanced Java
    Replies: 2
    Last Post: 07-17-2007, 08:16 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •