How to Set Auto-Scrolling of Jtextarea in Java Gui

How to set AUTO-SCROLLING of JTextArea in Java GUI?

When using JDK1.4.2 (or earlier) the most common suggestion you will find in the forums is to use code like the following:

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

However, I have just noticed that in JDK5 this issue has actually been resolved by an API change. You can now control this behaviour by setting a property on the DefaultCaret of the text area. Using this approach the code would be:

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

Note:

The above suggestion to set the caret update policy does not work.

Instead you may want to check out Smart Scrolling which gives the user the ability to determine when scrolling should be automatic or not.

A more detailed description of automatic scrolling in a text area can be found here: Text Area Scrolling

How to make JTextArea autoscroll

You need to remove this line from your code:

consoleOutput.setPreferredSize(new Dimension( 200,300));

Unfortunately, it prevents your JTextArea from being scrollable because you set static size to that element.

P.S. Stay away from Swing - there are better options in Java

How to auto scroll down JTextArea after append?

there are two ways (but JTextArea must be placed in JScrollPane)

a) set Caret (correct of ways)

e.g.

  DefaultCaret caret = (DefaultCaret) log.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

b) moving with JScrollBar (from JScrollPane) to its max value

Auto-scroll JTextArea with ScrollPane?

Never do this:

actionLog.setPreferredSize(new Dimension(500, 300));

Since by doing this you artificially restrict the size of the JTextArea causing the effect that is currently vexing you. Note also that it's generally a good idea to avoid setting preferred sizes on anything.

Instead set the column and row counts of the JTextARea. This can be done via setter methods or via a simple constructor call: JTextArea myTextArea = new JTextArea(rows, columns);

As an aside: I wonder if a JList will work better for you.


MCVE Example:

import javax.swing.*;
import javax.swing.text.DefaultCaret;

public class Main2 {

private static void createAndShowGUI() {
JPanel mainPanel = new ControlPanel();

JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

class ControlPanel extends JPanel {
private static final int LOG_ROWS = 15;
private static final int LOG_COLS = 40;
private JButton resetButton = new JButton("Reset");
private JPanel logPanel = new JPanel();
private JLabel actionLogsLabel = new JLabel("Action Log");
private JLabel pointsLogsLabel = new JLabel("Points Log");
private JTextArea actionLog = new JTextArea();
private JTextArea pointsLog = new JTextArea();
private JScrollPane actionScroll;
private JScrollPane pointsScroll;

public ControlPanel() {
init();
this.add(resetButton);
this.add(logPanel);
}

private void init() {
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setAlignmentX(LEFT_ALIGNMENT);
this.logPanel.setLayout(new BoxLayout(logPanel, BoxLayout.Y_AXIS));
this.logPanel.setAlignmentX(LEFT_ALIGNMENT);
// !! actionLog.setPreferredSize(new Dimension(500, 300));
// !! actionLog.setMaximumSize(actionLog.getPreferredSize());
actionLog.setRows(LOG_ROWS); // !!
actionLog.setColumns(LOG_COLS); // !!

actionLog.setEditable(false);
actionLog.setWrapStyleWord(true);
DefaultCaret caret = (DefaultCaret) actionLog.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
// !! pointsLog.setPreferredSize(new Dimension(500, 300));
// !! pointsLog.setMaximumSize(pointsLog.getPreferredSize());
pointsLog.setRows(LOG_ROWS); // !!
pointsLog.setColumns(LOG_COLS); // !!

pointsLog.setEditable(false);
pointsLog.setWrapStyleWord(true);
pointsScroll = new JScrollPane(pointsLog,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
actionScroll = new JScrollPane(actionLog,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
logPanel.add(actionLogsLabel);
logPanel.add(actionScroll);
for (int i = 0; i < 500; i++) {
actionLog.setText(actionLog.getText() + "Line: " + i + "\n");
}
logPanel.add(pointsLogsLabel);
logPanel.add(pointsScroll);
}
}

Edit
Example with nested layouts and JLists:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.*;

public class Main2B {

private static void createAndShowGUI() {
ControlPanel2B controlPanel = new ControlPanel2B();
controlPanel.setBorder(BorderFactory.createEtchedBorder());

JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
mainPanel.add(controlPanel, gbc);

JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

@SuppressWarnings("serial")
class ControlPanel2B extends JPanel {
private static final int LOG_ROWS = 15;
private static final int LIST_WIDTH = 500;
private JButton resetButton = new JButton("Reset");
private JPanel logPanel = new JPanel();
private JLabel actionLogsLabel = new JLabel("Action Log");
private JLabel pointsLogsLabel = new JLabel("Points Log");

private DefaultListModel<String> actionLogListModel = new DefaultListModel<>();
private JList<String> actionLogList = new JList<String>(actionLogListModel);
private DefaultListModel<String> pointsLogListModel = new DefaultListModel<>();
private JList<String> pointsLogList = new JList<String>(pointsLogListModel);
private JScrollPane actionScroll;
private JScrollPane pointsScroll;

public ControlPanel2B() {
init();
this.add(resetButton);
this.add(logPanel);
}

private void init() {
actionLogList.setVisibleRowCount(LOG_ROWS);
pointsLogList.setVisibleRowCount(LOG_ROWS);
actionLogList.setFixedCellWidth(LIST_WIDTH);

this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.setAlignmentX(LEFT_ALIGNMENT);
this.logPanel.setLayout(new BoxLayout(logPanel, BoxLayout.Y_AXIS));
this.logPanel.setAlignmentX(LEFT_ALIGNMENT);
pointsScroll = new JScrollPane(pointsLogList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
actionScroll = new JScrollPane(actionLogList,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
logPanel.add(actionLogsLabel);
logPanel.add(actionScroll);
for (int i = 0; i < 500; i++) {
actionLogListModel.addElement("Line: " + i);
}
logPanel.add(pointsLogsLabel);
logPanel.add(pointsScroll);
}
}

How to continue autoscroll in JTextArea after mouse click?

This mechanism of auto-scroll relies on the cursor always being at the very end of the content of the text area. For as long as the cursor is at the end, you have auto-scrolling. The moment the cursor goes anywhere else but the end, auto-scrolling ceases.

So, in order to resume auto-scrolling, the only thing you need to do is move the cursor to the very end. You can look for a way to do this programmatically, but until then you can just hit Ctrl+End when you want auto-scrolling to resume.

Also please note that I found several warnings in your code, which means that you are programming without many useful warnings enabled, which tends to be very error-prone business.

Java / Swing : JTextArea in a JScrollPane, how to prevent auto-scroll?

How to set AUTO-SCROLLING of JTextArea in Java GUI?

http://download.oracle.com/javase/1.5.0/docs/api/javax/swing/text/DefaultCaret.html#NEVER_UPDATE

Try:

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);

This should prevent the caret from automatically making the document scroll to the bottom.

auto scroll jtextarea only for lines

Check out Smart Scrolling

It managers the scrolling without using the caret policy. So you are in better control of the scrolling functionality.

If uses an AdjustmentListener on the vertical scrollbar to determine when scrolling should be done.



Related Topics



Leave a reply



Submit