如何在JFrame中为长文本JTextArea正确实现滚动功能
问题背景
开发Java Swing桌面程序时,需要实现一块正方形的可滚动文本区域用于展示长文本,多次调整实现后仍存在文本超出区域长度被截断的问题,原有问题代码如下:
package gerador; import java.awt.BorderLayout; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.border.EmptyBorder; import javax.swing.JTextArea; import javax.swing.Scrollable; public class frameMyPasswords extends JFrame { private JPanel contentPane; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { frameMyPasswords frame = new frameMyPasswords(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public frameMyPasswords() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); JTextArea txtField = new JTextArea(); txtField.setLineWrap(true); txtField.setEditable(false); txtField.setToolTipText(""); txtField.setBounds(10, 38, 419, 144); txtField.setText("LONG TEXT"); contentPane.add(txtField); } }
问题根因
- 代码中虽然导入了
JScrollPane类,但从未实际实例化滚动面板,也未将文本域放入滚动容器中,直接把文本域添加到使用null绝对布局的内容面板上,文本超出setBounds设定的固定尺寸后没有滚动条支持,必然出现截断。 - 内容面板使用
null绝对布局属于Swing开发中的反模式,组件尺寸、位置不会随窗口大小变化自适应,极易出现各类显示异常。 - 仅开启了行自动换行
setLineWrap(true),未开启按单词断行的配置setWrapStyleWord(true),连续长文本、无空格长串内容仍可能出现横向溢出。
修复实现
核心修改逻辑:
- 移除
null绝对布局,使用标准布局管理器托管组件位置尺寸 - 实例化
JScrollPane,将JTextArea作为滚动面板的视图组件,自动获得纵向/横向滚动支持 - 补全
setWrapStyleWord(true)配置,避免长文本横向溢出 - 通过设置首选尺寸实现正方形的文本区域要求,不需要手动写固定坐标
修正后的可运行代码如下:
package gerador; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.border.EmptyBorder; import javax.swing.JTextArea; public class frameMyPasswords extends JFrame { private JPanel contentPane; /** * 程序启动入口 */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { frameMyPasswords frame = new frameMyPasswords(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * 窗口初始化 */ public frameMyPasswords() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); // 移除null布局,使用边界布局 contentPane.setLayout(new BorderLayout(10, 10)); setContentPane(contentPane); JTextArea txtField = new JTextArea(); // 开启自动换行 txtField.setLineWrap(true); // 开启按单词断行,避免长串内容横向溢出 txtField.setWrapStyleWord(true); txtField.setEditable(false); txtField.setToolTipText(""); txtField.setText("这里替换为需要展示的长文本内容"); // 将文本域放入滚动面板 JScrollPane scrollPane = new JScrollPane(txtField); // 设置滚动面板首选尺寸为正方形,可根据需要调整边长数值 scrollPane.setPreferredSize(new Dimension(400, 400)); contentPane.add(scrollPane, BorderLayout.CENTER); // 自动调整窗口大小适配内容 pack(); setLocationRelativeTo(null); // 窗口居中显示 } }
内容的提问来源于stack exchange,提问作者Lucas Almeida
相关产品推荐
相关产品推荐

