您的代码有问题:
>通过设置JTextArea的边界来限制其大小.无论何时使用setBounds,setSize或setPreferredSize进行此操作,都将使JTextArea的大小变刚性,因此,如果向其中添加大于此大小的文本,则JTextArea不会扩展.这样做通常会导致包含JScrollPane的对象在需要时显示滚动条,因为JTextArea在需要时不会扩展.
>您正在使用空布局.尽管null布局和setBounds()似乎是Swing新手喜欢创建复杂GUI的最简单和最佳方法,但您创建的Swing GUI越多,使用它们时将遇到的困难就越大.当GUI调整大小时,它们不会重新调整组件的大小;它们是需要增强或维护的皇家女巫;放置在滚动窗格中时,它们会完全失败;在所有平台或与原始分辨率不同的屏幕分辨率下查看时,它们看起来都令人作呕.
>您要将JTextArea添加到两个容器(GUI和JScrollPane),而这在Swing GUI中是不允许的.
代替:
>通过设置JTextArea的行和列属性来限制其显示的大小,将它们传递到JTextArea的两个int构造函数中最容易实现.
>使用嵌套的JPanels,每个JPanels具有自己的布局,以实现复杂,灵活而又有吸引力的GUI.
>仅将JTextArea添加到JScrollPane的视口,然后将JScrollPane添加到GUI.
例如,假设您希望在GUI中心的JScrollPane内有一个JTextArea,在顶部有一个按钮,在下面有一个JTextField和一个Submit按钮,例如一个典型的聊天窗口类型的应用程序,您可以使整体布局成为BorderLayout,添加一个使用GridLayout的JPanel到顶部带有按钮,使用Box的JPanel带有JTextField并提交按钮到底部,而JScrollPane则将JTextArea放在中心.它可能看起来像这样:
代码看起来像这样:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class Experiment2 extends JPanel {
private static final int ROWS = 20;
private static final int COLUMNS = 50;
private static final int GAP = 3;
// create the JTextArea, setting its rows and columns properties
private JTextArea tarea = new JTextArea(ROWS, COLUMNS);
private JTextField textField = new JTextField(COLUMNS);
public Experiment2() {
// create the JScrollPane and pass in the JTextArea
JScrollPane scrollPane = new JScrollPane(tarea);
// let's create another JPanel to hold some buttons
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0));
buttonPanel.add(new JButton("Save"));
buttonPanel.add(new JButton("Load"));
buttonPanel.add(new JButton("Whatever"));
buttonPanel.add(new JButton("Exit"));
// create JPanel for the bottom with JTextField and a button
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
bottomPanel.add(textField);
bottomPanel.add(Box.createHorizontalStrut(GAP));
bottomPanel.add(new JButton("Submit"));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
// use BorderLayout to add all together
setLayout(new BorderLayout(GAP, GAP));
add(scrollPane, BorderLayout.CENTER); // add scroll pane to the center
add(buttonPanel, BorderLayout.PAGE_START); // and the button panel to the top
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
Experiment2 mainPanel = new Experiment2();
JFrame frame = new JFrame("Experiment 2");
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(() -> createAndShowGui());
}
}
编辑
让我们进行实验并创建一个包含两个JTextAreas的GUI,而不是猜测什么有效,什么不起作用,其中一个由colRowTextArea变量设置并保存column和rows属性,另一个由JTextArea的首选大小设置,并将其变量称为prefSizeTextArea.
我们将创建一个方法setUpTextArea(…),将JTextArea放入JScrollPane中,再将其放入JPanel中,并具有一个将大量文本添加到JTextArea中的按钮,并查看操作的结果.添加文本时的JTextArea.
这是代码,然后按一下按钮,然后自己查看滚动的内容:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class TwoTextAreas extends JPanel {
// our nonsense String
public static final String LoremIpsum = "Lorem ipsum dolor sit amet, "
+ "consectetur adipiscing elit, sed do eiusmod tempor incididunt "
+ "ut labore et dolore magna aliqua. Ut enim ad minim veniam, "
+ "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea "
+ "commodo consequat. Duis aute irure dolor in reprehenderit in "
+ "voluptate velit esse cillum dolore eu fugiat nulla pariatur. "
+ "Excepteur sint occaecat cupidatat non proident, sunt in culpa "
+ "qui officia deserunt mollit anim id est laborum.";
private static final int ROWS = 30;
private static final int COLS = 40;
private static final Dimension TA_PREF_SIZE = new Dimension(440, 480);
private JTextArea colRowTextArea = new JTextArea(ROWS, COLS);
private JTextArea prefSizeTextArea = new JTextArea();
public TwoTextAreas() {
setLayout(new GridLayout(1, 0));
prefSizeTextArea.setPreferredSize(TA_PREF_SIZE);
add(setUpTextArea(colRowTextArea, "Set Columns & Rows"));
add(setUpTextArea(prefSizeTextArea, "Set Preferred Size"));
}
private JPanel setUpTextArea(JTextArea textArea, String title) {
// allow word wrapping
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
JScrollPane scrollPane = new JScrollPane(textArea);
JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AppendTextAction(textArea)));
JPanel holderPanel = new JPanel(new BorderLayout());
holderPanel.setBorder(BorderFactory.createTitledBorder(title));
holderPanel.add(scrollPane);
holderPanel.add(buttonPanel, BorderLayout.PAGE_END);
return holderPanel;
}
private class AppendTextAction extends AbstractAction {
private JTextArea textArea;
private StringBuilder sb = new StringBuilder();
public AppendTextAction(JTextArea textArea) {
super("Append Text to TextArea");
this.textArea = textArea;
// create nonsense String
for (int i = 0; i < 100; i++) {
sb.append(LoremIpsum);
sb.append("
");
}
}
@Override
public void actionPerformed(ActionEvent e) {
textArea.append(sb.toString());
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Two TextAreas");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new TwoTextAreas());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}