当 Frame 拆分为两个 JPanel 时,JTextArea 不起作用

JTextArea doesn't work when Frame is split in two JPanel

我想把我的Frame分成两个JPanel,右边的JPanel作为textarea用来输入和显示。 但是,我无法在其中输入任何内容,也无法显示任何内容。 代码如下:

JPanel jp1, jp2;
public DemoFrame() {
    jp1 = new JPanel();
    jp2 = new JPanel();
    JLabel label = new JLabel("text");
    JTextArea ta = new JTextArea(100,100);
    ta.setText("some text");
    ta.setSize(300, 300);
    jp2.add(label);
    jp2.add(ta);
    JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jp1, jp2);
    this.getContentPane().add(jsp);;
    setBounds(300, 200, 500, 500);
    setVisible(true);
    jsp.setDividerLocation(0.5);// 
} 

输出如下(不显示任何内容):

恭喜,您已成为一系列阴谋问题的受害者。

罪魁祸首是 FlowLayout,它是 JPanel 的默认布局管理器。本质上,当您将相当大的 JTextArea 添加到面板时,FlowLayout 试图在可用 space 的限制内尽可能地遵守首选大小。由于我不能 100% 确定的原因,这意味着将组件布置在容器的可见边界之外。

如果您输入的文字足够多,您就会开始看到它。

虽然有多种方法可以解决此问题,但它们基本上是相同的解决方案 - 使用不同的布局管理器。

对于这个例子,我只是使用了 BorderLayout 而不是

import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    private JPanel jp1, jp2;

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                jp1 = new JPanel();
                jp2 = new JPanel(new BorderLayout());
                JLabel label = new JLabel("text");
                JTextArea ta = new JTextArea(50, 50);
                ta.setText("some text");
                jp2.add(label, BorderLayout.NORTH);
                jp2.add(new JScrollPane(ta));
                JSplitPane jsp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jp1, jp2);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(jsp);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}