automatic dynamic expansion / contraction of JTextArea in Java

£可爱£侵袭症+ 提交于 2020-01-15 08:56:07

问题


I start off by creating a JTextArea of a specific size. The user can add text within it but it will get cut off if it becomes too long (vertically or horizontally). I want the JTextArea to automatically expand or contract (for deletion of text).

I may allow users to change font and font size in the future, so it would be good if I could avoid making things increase/decrease by a certain size.

I am currently using bounds to size my JTextArea. Perhaps I should size by rows and columns and use a listener and act appropriately?

thanks in advance!


回答1:


I can't imagine why you'd want to do this, why not put a JTextArea in a JScrollPane, but ok, i'll play along... Maybe something like this:

import java.awt.Container;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;


public class Expander extends JFrame {

    private final JTextArea area;
    private int hSize = 1;
    private int vSize = 1;

    public Expander() {
        Container cp = getContentPane();
        cp.setLayout(new BoxLayout(cp, BoxLayout.Y_AXIS));

        cp.add(Box.createHorizontalGlue());
        area = new JTextArea(vSize, hSize);
        cp.add(area);
        cp.add(Box.createHorizontalGlue());

        area.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                adjust();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                adjust();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                adjust();
            }
        });

        pack();
    }

    private void adjust() {
        int maxColumns = getMaxColumns();
        if ((area.getLineCount() != vSize) || (maxColumns != hSize)) {
            hSize = maxColumns;
            vSize = area.getLineCount();
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    area.setColumns(hSize);
                    area.setRows(vSize);
                    Expander.this.doLayout();
                    Expander.this.pack();
                }
            });
        }
    }

    private int getMaxColumns() {
        int startOffset = 0;
        int maxColumns = 0;
        for (int i = 0; i < area.getLineCount(); i++) {
            try {
                int endOffset = area.getLineEndOffset(i);
                int lineSize = endOffset - startOffset;
                if (lineSize > maxColumns) {
                    maxColumns = lineSize;
                }
                startOffset = endOffset;
            } catch (BadLocationException ble) {
            }
        }

        return maxColumns;
    }

    public static void main(String[] args) {

        Expander e = new Expander();
        e.setLocationRelativeTo(null);
        e.setVisible(true);
    }
}



回答2:


I second the advice to simply put the JTextArea in a JScrollPane and let this take care of extra text. Also and perhaps most importantly, don't set the bounds of the JTextArea because if you do this, you constrain it to be a certain size and that's not what you want to have happen. Instead initialize your JTextArea with two int constants to represent the number of rows and columns that should be visualized and then place it in a JScrollPane. Also be sure to read up on using the layout managers so you can avoid setting the size of your JScrollPane too!

Edit: on testing, it seems that setPreferredSize is more dangerous to a JTextArea than setSize.

import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.*;

public class ConstrainedTextArea extends JPanel {
   private JTextArea textArea1, textArea2, textArea3;

   public ConstrainedTextArea() {
      textArea1 = new JTextArea(20, 30);
      textArea2 = new JTextArea();
      textArea3 = new JTextArea();

      textArea2.setPreferredSize(new Dimension(300, 300));
      textArea3.setSize(textArea3.getPreferredSize());

      setLayout(new GridLayout(1, 0));
      add(new JScrollPane(textArea1));
      add(new JScrollPane(textArea2));
      add(new JScrollPane(textArea3));
   }

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

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



回答3:


also, see GrowingTextAreaExample



来源:https://stackoverflow.com/questions/5943672/automatic-dynamic-expansion-contraction-of-jtextarea-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!