简体   繁体   中英

Java JTextArea allow scrolling beyond end of text

Java's text areas don't allow scrolling beyond the end of the text normally, but sometimes it is more comfortable to allow ie the bottom of the text to be at the middle of the window. Is there an easy way to do this?

If I understand you correctly, you could simply set the row property of the JTextArea to be large enough so that the text does not completely fill it.

eg,

import javax.swing.*;

public class MyLargeTextArea extends JPanel {

    private static final int ROWS = 20;
    private static final int COLS = 40;
    private JTextArea textArea = new JTextArea(ROWS, COLS);

    public MyLargeTextArea() {
        textArea.setText("This is a small amount of text");

        // so lines wrap
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);

        add(new JScrollPane(textArea));
    }

    private static void createAndShowGui() {
        MyLargeTextArea mainPanel = new MyLargeTextArea();

        JFrame frame = new JFrame("MyLargeTextArea");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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

What you should never do is to set the size, bounds, or preferredSize of a JTextArea as that would inhibit its desired behavior to expand as needed if text is added and filling it with text beyond its current visualized size.

Edit:

This is how eg Visual Studio behaves. You can have the last line of the text as the first line of the scrolling area

You can adjust the preferred height of the text area to allow the last line to be scrolled to the top of the text area:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;    

public class TextAreaTop
{
    private static void createAndShowGUI()
    {
        JTextArea textArea = new JTextArea(6, 30)
        {
            @Override
            public Dimension getPreferredSize()
            {
                Dimension preferred = super.getPreferredSize();
                int heightAdjustment = getParent().getSize().height - getRowHeight();
                preferred.height += heightAdjustment;

                Border border = getBorder();

                if (border != null)
                    preferred.height -= border.getBorderInsets(this).bottom;

                return preferred;
            }
        };

        textArea.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n0");
        textArea.setBorder( new EmptyBorder(20, 20, 20, 20) );

        JScrollPane scrollPane = new JScrollPane( textArea );

        JFrame frame = new JFrame("TextAreaTop");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(scrollPane);
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

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




Original answer (which can probably be ignored):

the bottom of the text to be at the middle of the window

If the bottom of the text is always at the middle that means the bottom half of the text area will never be used so you have wasted space. I would think this will confuse the user.

However, you can add a Border to the text area. This will allow you to leave a little extra space at the bottom when fully scrolled:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.border.*;

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        setLayout( new BorderLayout() );

        JTextArea textArea = new JTextArea(10, 30);
        textArea.setText("1\n2\n3\n4\n5\n6\n7\n8\n9\n0");
        textArea.setBorder( new EmptyBorder(0, 0, 48, 0) );

        add( new JScrollPane(textArea) );
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.setSize(400, 200);
        frame.setVisible( true );
    }

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

If you want to get a little fancy you could also add the following. This code will attempt to center the line where the caret is located.

textArea.addCaretListener( new CaretListener()
{
    public void caretUpdate(CaretEvent e)
    {
        JTextComponent component = (JTextComponent)e.getSource();
        RXTextUtilities.centerLineInScrollPane( component );
    }
});

To use the above code you will need the Text Utilities class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM