XYZEK 0
XYZEK 0

Reputation: 13

How to make JTextArea autoscroll

i have problem with my JTextArea i java. When i print output in the text area, it doesn't automatically scroll to the bottom. And when it reaches the bottom of text area i cannot scroll it with scroll panel. Here is my GUI Code:

public void initializeWindow()
    {
        JPanel pan;
        JPanel colorBox;
        JPanel consolePanel;
        JLabel panText;
        JFrame frame = new JFrame();
        JScrollPane scroll;


        gridPanels = new JPanel[sizeX][sizeY];
        boardPanel = new JPanel();
        legend = new JPanel();
        consolePanel = new JPanel();
        consoleOutput = new JTextArea(25,20);


        consoleOutput.setEditable(false);
        consoleOutput.setPreferredSize(new Dimension( 200,300));
        consoleOutput.setAutoscrolls(true);

        scroll = new JScrollPane(this.consoleOutput, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        consolePanel.setBorder(BorderFactory.createLineBorder(Color.black));
        consolePanel.add(consoleOutput);
        consolePanel.add(scroll);


        boardPanel.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
        boardPanel.setLayout(new GridLayout(sizeX,sizeY));

        legend.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
        legend.setPreferredSize( new Dimension(300,boardPanel.getHeight()));


        PrintStream printStream = new PrintStream(new CustomOutputStream(consoleOutput));


        for (Organizm org: legendOrgs)
        {
            pan = new JPanel();
            colorBox = new JPanel();
            panText = new JLabel();

            pan.setMaximumSize(new Dimension(100,70));
            pan.setAlignmentX(Component.LEFT_ALIGNMENT);
            pan.setLayout(new FlowLayout(FlowLayout.LEADING));

            colorBox.setBackground(org.getOrgColor());
            colorBox.setAlignmentX(Component.LEFT_ALIGNMENT);
            colorBox.setPreferredSize(new Dimension(30,30));
            colorBox.setMaximumSize(new Dimension(30,30));

            panText.setPreferredSize(new Dimension(100,15));
            panText.setText(" - " + org.getName());
            panText.setAlignmentX(Component.RIGHT_ALIGNMENT);

            pan.add(colorBox);
            pan.add(panText);

            legend.add(pan);
        }
        legend.add(consolePanel);

        for(int i=0; i<sizeY; i++)
        {
            for(int j=0; j<sizeX; j++)
            {
                gridPanels[i][j] = new JPanel();
                if(organizmy[i][j]!=null)
                    gridPanels[i][j].setBackground(organizmy[i][j].getOrgColor());
                else gridPanels[i][j].setBackground(Color.white);
                boardPanel.add(gridPanels[i][j]);
            }
        }

        System.setOut(printStream);
        System.setErr(printStream);
        frame.add(boardPanel);
        frame.add(legend,BorderLayout.EAST);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Wirtualny świat");
        frame.pack();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setVisible(true);
        worldFrame = frame;
    }

And here is my Custom output Stream class which is used to print everything i print via System.out.println to my text Area:

public class CustomOutputStream extends OutputStream
{
    private final JTextArea textArea;

    public CustomOutputStream(JTextArea textArea)
    {
        this.textArea = textArea;
    }

    @Override
    public void write(int b)
    {
        textArea.append(String.valueOf((char)b));
        textArea.setCaretPosition(textArea.getDocument().getLength());
    }




}

Here is link to image what it looks like in GUI:

Upvotes: 1

Views: 330

Answers (2)

matt
matt

Reputation: 12347

It works for me.

import javax.swing.*;
public class Scrollin{

    public static void main(String[] args){
        JFrame frame = new JFrame("scrolling");
        JTextArea area = new JTextArea(20, 20);
        
        frame.add(new JScrollPane(area));
        frame.setVisible(true);
        frame.pack();
        Timer t = new Timer( 150, evt->{
            area.setCaretPosition( area.getDocument().getLength() );
            area.append("word is born\n");
        });
        t.start();
    }
}

As text is added, the window will scroll to the end provided the cursor is at the end of the document.

Maybe you can start with something as short as this to demonstrate your issue?

Upvotes: 0

Czumpi
Czumpi

Reputation: 26

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

Upvotes: 1

Related Questions