devxlogo

Repositioning Viewable Text in TextArea

Repositioning Viewable Text in TextArea

Question:
Can I make the text in a TextArea scroll to a given line? For example, I have 100 lines of text in a TextArea with 20 viewable rows. Can I scroll the text (without manipulating the scrollbars physically) so that lines 70-90 are displayed in the TextArea?

Answer:
This is an excellent example of where you should use the Swing classes because of their enhanced functionality. With the regular AWT classes, it is almost impossible to scroll aTextArea automatically. To do so requires getting a reference to theTextArea‘s scrollbar and changing its value with setValue() or setValues(). But there is noway to get a reference to the scrollbar. There may be some intricate trickery you can go through to reach the desired result, but I cannot immediately see it.

Life is much simpler if you use JTextArea. Rather, I should say it is possible to do many more things withJTextArea. The Swing classes are powerful and often simple to use, but also have some idiosyncracies that can entail greater complexity. JTextArea stores its text as a linear sequence of characters, indexed by a single offset. This makes it difficult to reference its contents on a row and column basis.You can, however, query the begin and end offsets of each line of text with getLineStartOffset andgetLineEndOffset. Once you obtain a location offset, you have to convert it to a view coordinate to scroll down to that position.

Unlike TextArea, JTextArea does not have a built-in set of scrollbars. None of the Swing classes do. To create a scrollable component, you have to add it to a JScrollPane. Each component stores a model of its contents that it converts to a coordinate that can be used by the scroll view to position and draw the scrolling area. ForJTextArea, that model implements thejavax.swing.text.Document interface. The class in charge of rendering the component subclasses javax.swing.text.View. These classes need not always be accessed directly because JTextArea contains convenience methods such as modelToView and the already mentionedgetLineStartOffset. The modelToView method will convert a document offset into a view coordinate. Now you have all the pieces necessary to scroll the JTextArea automatically.

See also  Why ChatGPT Is So Important Today

Once you obtain a view coordinate, all you have to do is tell the ScrollPane viewport to move to a new position by callingsetViewPosition. The following code listing demonstrates how to make a JTextArea scroll to an arbitrary row. The only tricky part is to remember that a component already must be painted before you call setViewPosition.

import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.text.*;public final class ScrollText extends JFrame {  public static final int FIRST_VISIBLE_ROW = 69;  private JTextArea __textArea;  private JScrollPane __scrollPane;  public ScrollText() {    super("Scroll Text Demo");    Container contentPane;    __textArea = new JTextArea();    __textArea.setColumns(40);    __textArea.setRows(20);    for(int row=1; row < 100; row++)      __textArea.append(Integer.toString(row) + "
");    __scrollPane = new JScrollPane();    __scrollPane.getViewport().add(__textArea);    contentPane = getContentPane();        contentPane.setLayout(new BorderLayout());    contentPane.add(__scrollPane, BorderLayout.CENTER);  }  public void scrollToRow(int row) {    int offset;    JViewport viewport;    Rectangle startLocation;    viewport = __scrollPane.getViewport();    try {      offset =	__textArea.getLineStartOffset(FIRST_VISIBLE_ROW);      startLocation = __textArea.modelToView(offset);      viewport.setViewPosition(new Point(startLocation.x, startLocation.y));    } catch(BadLocationException e) {    }  }  public static void main(String[] args) {    final ScrollText demo;    WindowListener exitListener;    exitListener = new WindowAdapter() {      public void windowClosing(WindowEvent e) {	Window window = e.getWindow();	window.setVisible(false);	window.dispose();	System.exit(0);      }    };    demo = new ScrollText();    demo.addWindowListener(exitListener);    demo.pack();    demo.setVisible(true);    // We have to make sure the JTextArea is painted before    // changing the viewport position.  Otherwise modelToView()    // will return null (see source to JTextComponent and    // javax.swing.plaf.basic.BasicTextUI).  Calling setVisible does    // not guarantee that the window will be painted before    // scrollToRow() is called.    Dimension size = demo.getSize();    ((JComponent)(demo.getContentPane())).paintImmediately(				   0, 0, size.width, size.height);    demo.scrollToRow(FIRST_VISIBLE_ROW);  }}
devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist