您的代码存在问题:
- 您可以通过设置 JTextArea 的边界来限制其大小。每当您执行此操作时,无论是使用 setBounds、setSize 或 setPreferredSize,您都会设置 JTextArea 的大小rigid因此,如果添加的文本大于此大小,它就不会扩展。这样做通常会导致包含的 JScrollPane 在需要时显示滚动条,因为 JTextArea 在需要时不会展开。
- 您正在使用空布局。虽然空布局和
setBounds()
对于 Swing 新手来说,Swing GUI 似乎是创建复杂 GUI 的最简单、最好的方法,您创建的 Swing GUI 越多,使用它们时遇到的困难就越严重。当 GUI 调整大小时,它们不会调整组件的大小,它们是增强或维护的皇家女巫,当放置在滚动窗格中时它们完全失败,当在与原始平台或屏幕分辨率不同的所有平台或屏幕分辨率上查看时,它们看起来非常糟糕。
- 您要将 JTextArea 添加到两个容器(GUI 和 JScrollPane),而这在 Swing GUI 中是不允许的。
Instead:
- 约束查看尺寸通过设置 JTextArea 的行和列属性,最简单的方法是将这些属性传递到 JTextArea 的两个 int 构造函数中。
- 使用嵌套的 JPanel,每个 JPanel 都有自己的布局,以实现复杂但灵活且有吸引力的 GUI。
- 仅将 JTextArea 添加到 JScrollPane 的视口,然后将 JScrollPane 添加到 GUI。
例如,假设您想要在 GUI 中心的 JScrollPane 内有一个 JTextArea,顶部有按钮,下面有一个 JTextField 和一个提交按钮,比如说一个典型的聊天窗口类型应用程序,您可以将整体布局设为 BorderLayout,添加一个GridLayout - 使用 JPanel,按钮位于顶部,BoxLayout 使用 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());
}
}
EDIT
与其猜测什么有效,什么无效,让我们试验并创建一个包含两个 JTextArea 的 GUI,其中一个由 colRowTextArea 变量设置和保存列和行属性,另一个设置 JTextArea 的首选大小,并将其变量称为 prefSizeTextArea。
我们将创建一个方法,setUpTextArea(...)
我们将 JTextArea 放入 JScrollPane 中,将其放入 JPanel 中,并有一个按钮可以添加lots将文本添加到 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("\n");
}
}
@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());
}
}