如何使用户可调整大小的 JTextArea?

How to make user-resizable JTextArea?

似乎唯一的选择是设置行数,但我需要为用户调整文本区域的大小。 JScrollPane 有帮助,但是当有很多文本时,我想让用户自己调整区域大小。

我该怎么做?如果我可以为此目的使用另一个 class,我会完全接受它。

简化代码为

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

public class Problematic {

    public static void main(String[] args) {
        JFrame f = new JFrame("frame");
        f.setLayout(new BorderLayout());

        JPanel p1 = new JPanel();
        JPanel p = new JPanel();

        JButton button = new JButton("Whatever here");
        JTextArea t2 = new JTextArea(5, 30);

        JScrollPane scrollPane = new JScrollPane(t2);

        scrollPane.setSize(600, 400);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        t2.setText("this is some random text\nthat may go for many rows\nso it may look messy");

        p1.add(button);
        p.add(scrollPane);

        f.add(p, BorderLayout.NORTH);
        f.add(p1, BorderLayout.CENTER);

        f.setSize(600, 500);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

作为第一个改进,您可以进行一些小的布局更改,使 JTextArea 占据整个 space 并随框架调整大小:

import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;

public class Problematic {

    public static void main(String[] args) {
        JFrame f = new JFrame("frame");
        f.setLayout(new BorderLayout()); 

        JPanel p = new JPanel(new GridLayout(1, 1)); //assign gridlayout so text area fills panel 
        JTextArea t2 = new JTextArea(5, 30);
        t2.setText("this is some random text\nthat may go for many rows\nso it may look messy");

        JScrollPane scrollPane = new JScrollPane(t2);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        p.add(scrollPane);
        f.add(p, BorderLayout.CENTER); //place text area panel in center position 

        JPanel p1 = new JPanel();
        JButton button = new JButton("Whatever here");
        p1.add(button);
        f.add(p1, BorderLayout.PAGE_END);

        f.setSize(600, 500);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

为了更加灵活,您可以添加 JSplitPane :

public class Problematic {

    public static void main(String[] args) {
        JFrame f = new JFrame("frame");
        f.getContentPane().setLayout(new BorderLayout());

        JPanel p1 = new JPanel();
        JButton button = new JButton("Whatever here");
        p1.add(button);

        JPanel p = new JPanel(new GridLayout(1, 1)); //assign gridlayout so text area fills panel
        JTextArea t2 = new JTextArea(5, 30);
        t2.setText("this is some random text\nthat may go for many rows\nso it may look messy");

        JScrollPane scrollPane = new JScrollPane(t2);       scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        p.add(scrollPane);

        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, p,p1);
        f.getContentPane().add(splitPane, BorderLayout.CENTER);

        f.setSize(600, 500);
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

您可以使用 JSplitPane 使 window 的各个区域可调整大小。试试下面的例子。也请参阅我在代码中的评论。

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

public class Problematic {

  public static void main(String[] args) {
    JFrame f = new JFrame("frame");
    f.setLayout(new BorderLayout());

    JPanel p1 = new JPanel();
    JPanel p = new JPanel();
    // Set BorderLayout so that scroll pane fills the panel
    p.setLayout(new BorderLayout());

    JButton button = new JButton("Whatever here");
    JTextArea t2 = new JTextArea(5, 30);

    JScrollPane scrollPane = new JScrollPane(t2);

    // Setting scroll pane size is not necessary
    //scrollPane.setSize(600, 400);
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    t2.setText("this is some random text\nthat may go for many rows\nso it may look messy");

    p1.add(button);
    p.add(scrollPane);

    // Use JSplitPane to make the panels resizable
    f.add(new JSplitPane(JSplitPane.VERTICAL_SPLIT, p, p1), BorderLayout.CENTER);

    f.setSize(600, 500);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}

这里是 c0der 的实现,但它是为了更简化的生命周期而设置的。每行都解释了发生的事情和时间。

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

public class TextApp implements Runnable {
    private static final String APP_NAME = "Text App";

    private JFrame frame;
    private JTextArea txtAra;
    private JButton button;

    // This is a generic action that handles clearing the text of a JTextComponent
    // It can also be a stand-alone class
    private static class ClearAction <T extends JTextComponent> implements ActionListener {
        private T txtAra;

        public ClearAction(T txtAra) {
            this.txtAra = txtAra;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            this.txtAra.setText("");
        }
    }

    public TextApp() {
        // Initialize instance fields
        frame = new JFrame(APP_NAME);
        txtAra = new JTextArea(5, 30);
        button = new JButton("Clear Text");

        // Internal panels used for layout
        JPanel mainPanel = new JPanel(new GridLayout(1, 1));
        JScrollPane scrollPane = new JScrollPane(txtAra);
        JPanel buttonPanel = new JPanel();

        // Add components to containers
        frame.setLayout(new BorderLayout());
        frame.add(mainPanel, BorderLayout.CENTER);
        frame.add(buttonPanel, BorderLayout.PAGE_END);
        mainPanel.add(scrollPane);
        buttonPanel.add(button);

        // Additional setup
        scrollPane.setSize(600, 400);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        // Add listeners
        button.addActionListener(new ClearAction(txtAra));
    }

    @Override
    public void run() {
        // Set text
        txtAra.setText("this is some random text\nthat may go for many rows\nso it may look messy");

        // Prepare frame
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

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