Java中JTextArea的自动动态扩展/收缩

Java中JTextArea的自动动态扩展/收缩,java,swing,user-interface,jtextfield,jtextarea,Java,Swing,User Interface,Jtextfield,Jtextarea,我首先创建一个特定大小的JTextArea。用户可以在其中添加文本,但如果文本太长(垂直或水平),则会被截断。我希望JTextArea自动展开或收缩(用于删除文本) 我可能会允许用户在将来更改字体和字体大小,因此如果我可以避免将内容增加/减少一定的大小,这将是一件好事 我目前正在使用边界来调整JTextArea的大小。也许我应该按行和列来调整大小,使用一个侦听器并采取适当的行动 提前谢谢 我无法想象您为什么要这样做,为什么不在JScrollPane中放置一个JTextArea,但好吧,我会继续。

我首先创建一个特定大小的JTextArea。用户可以在其中添加文本,但如果文本太长(垂直或水平),则会被截断。我希望JTextArea自动展开或收缩(用于删除文本)

我可能会允许用户在将来更改字体和字体大小,因此如果我可以避免将内容增加/减少一定的大小,这将是一件好事

我目前正在使用边界来调整JTextArea的大小。也许我应该按行和列来调整大小,使用一个侦听器并采取适当的行动


提前谢谢

我无法想象您为什么要这样做,为什么不在JScrollPane中放置一个JTextArea,但好吧,我会继续。。。也许是这样的:

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);
    }
}
导入java.awt.Container;
导入javax.swing.Box;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
导入javax.swing.JTextArea;
导入javax.swing.SwingUtilities;
导入javax.swing.event.DocumentEvent;
导入javax.swing.event.DocumentListener;
导入javax.swing.text.BadLocationException;
公共类扩展器扩展JFrame{
私人住宅区;
私家侦探=1;
私有int-vSize=1;
公共扩展器(){
容器cp=getContentPane();
cp.setLayout(新的BoxLayout(cp,BoxLayout.Y_轴));
cp.add(Box.createHorizontalGlue());
面积=新的JTextArea(vSize,hSize);
cp.add(面积);
cp.add(Box.createHorizontalGlue());
area.getDocument().addDocumentListener(新DocumentListener()){
@凌驾
公共作废插入更新(文档事件e){
调整();
}
@凌驾
公共作废移除更新(文档事件e){
调整();
}
@凌驾
公共作废更改日期(记录事件e){
调整();
}
});
包装();
}
私人空间调整(){
int maxColumns=getMaxColumns();
if((area.getLineCount()!=vSize)| |(maxColumns!=hSize)){
hSize=最大列数;
vSize=area.getLineCount();
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
面积。设置列(hSize);
区域设置行(vSize);
Expander.this.doLayout();
Expander.this.pack();
}
});
}
}
私有int getMaxColumns(){
int startOffset=0;
int maxColumns=0;
对于(int i=0;i最大列){
maxColumns=线条尺寸;
}
STARTOFSET=内偏移;
}捕获(BadLocationException-ble){
}
}
返回maxColumns;
}
公共静态void main(字符串[]args){
扩展器e=新扩展器();
e、 setLocationRelativeTo(空);
e、 setVisible(真);
}
}

我支持将JTextArea放在JScrollPane中的建议,让它处理额外的文本。另外,也许最重要的是,不要设置JTextArea的边界,因为如果这样做,会将其限制为一定的大小,而这不是您想要的。相反,使用两个int常量初始化JTextArea,以表示应该可视化的行数和列数,然后将其放置在JScrollPane中。另外,请务必仔细阅读布局管理器的使用,这样您就可以避免设置JScrollPane的大小了

编辑:在测试中,setPreferredSize似乎比setSize对JTextArea更危险

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();
         }
      });
   }
}

另外,请参见

谢谢!我需要这样做,因为我需要所有的文本一次都可见。总的来说,我希望有这些“文本片段”,用户可以移动和互动。谢谢!我需要这样做,因为我需要所有的文本一次可见…所以我不能使用滚动条。总的来说,我希望有这些“文本片段”,用户可以移动和交互。