Tienanh Nguyen Tienanh Nguyen - 20 days ago 6
Java Question

How to put a changing JTextArea to JScrollPane?

I have code like this. I cut down all the details, but this text area will change after a press of a button and all it did was change the text area. No scrolling was added. I even tried to set the scroll policy to always but it returns an error. This panel will be added to another panel with BorderLayout.CENTER and then that panel will be added to a JFrame.

public class Tester extends JFrame{
JPanel panel = new JPanel();
public static void main(String[] args) {
new Tester();
}
public Tester(){
setSize(1300, 700);
setTitle("A Bar Chart");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel();
setVisible(true);
}
public void panel(){
JTextArea text = new JTextArea();
text.setPreferredSize(new Dimension(100, 100));
JScrollPane pane = new JScrollPane(text);
JButton button = new JButton("a");
button.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
text.setText("asd\nasdasd\nasdasd\nasdasd\nasdasd\nasdasd\na\na\na\n");

}
});
panel.add(pane);
panel.add(button);
add(panel);
}
}


I guess now that I just went and make it simpler. Maybe the problem is when I setText the size doesn't change so the scroll doesn't appear. So maybe now the question is how do I make the scroll appear or change it size so that the scroll appear.

Answer

You're shooting yourself in the foot with:

text.setPreferredSize(new Dimension(100, 100));

Never restrict a JTextArea's size this way as it will result in the problem you're seeing, since by restricting the preferred size, the JTextArea can't expand appropriately when its text takes up more room then the preferred size allows. Instead set the JTextArea's columns and rows properties, easiest to do with the appropriate constructor.

JTextArea text = new JTextArea(TEXT_AREA_ROWS, TEXT_AREA_COLUMNS);

e.g.,

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class Tester2 extends JPanel {
    private static final int TA_ROWS = 30;
    private static final int TA_COLS = 50;
    private JTextArea text = new JTextArea(TA_ROWS, TA_COLS);

    public Tester2() {
        text.setFocusable(false);
        JScrollPane scrollPane = new JScrollPane(text);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(new JButton(new ButtonAction("Press Me")));

        setLayout(new BorderLayout());
        add(scrollPane);
        add(buttonPanel, BorderLayout.PAGE_END);
    }

    private class ButtonAction extends AbstractAction {
        public ButtonAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 80; i++) {
                int wordsInSent = (int) (5 + 6 * Math.random()); 
                for (int j = 0; j < wordsInSent; j++) {
                    int wordLength = (int) (5 + 8 * Math.random());
                    for (int k = 0; k < wordLength; k++) {
                        char c = (char) ('a' + (int)(Math.random() * ('z' - 'a')));
                        sb.append(c);
                    }
                    sb.append(" ");
                }
                sb.append("\n");
            }
            text.append(sb.toString());
        }
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Tester2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Tester2());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
Comments