- 基本创建与使用
- 获取输入内容
- 监听输入变化 (核心)
- 限制输入内容
- 设置输入提示
- 完整示例代码
基本创建与使用
你需要创建一个 JTextField 实例。

import javax.swing.*;
import java.awt.*;
public class BasicTextField {
public static void main(String[] args) {
// 1. 创建窗口
JFrame frame = new JFrame("JTextField 基础示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 150);
frame.setLayout(new FlowLayout()); // 使用流式布局
// 2. 创建 JTextField
// JTextField textField = new JTextField(); // 默认创建一个空的文本框
JTextField textField = new JTextField(20); // 创建一个可以显示约20个字符宽度的文本框
// 3. 创建一个标签,用于提示用户
JLabel label = new JLabel("请输入您的姓名:");
// 4. 创建一个按钮,用于触发操作
JButton button = new JButton("提交");
// 5. 将组件添加到窗口
frame.add(label);
frame.add(textField);
frame.add(button);
// 6. 显示窗口
frame.setVisible(true);
}
}
代码解释:
JTextField textField = new JTextField(20);: 创建一个JTextField,参数20是一个建议的列数,它决定了文本框的宽度,但不限制输入的字符长度。FlowLayout: 一种简单的布局管理器,组件会像流水一样从左到右排列,一行放不下就换行。
获取输入内容
当你需要获取用户在 JTextField 中输入的文本时,最常用的方法是 getText()。
这个方法通常在某个事件(比如点击按钮)的监听器中被调用。
// 在上面的示例基础上,为按钮添加监听器
button.addActionListener(e -> {
// 获取 JTextField 中的文本
String inputText = textField.getText();
// 检查输入是否为空
if (inputText == null || inputText.trim().isEmpty()) {
JOptionPane.showMessageDialog(frame, "输入不能为空!", "提示", JOptionPane.WARNING_MESSAGE);
} else {
JOptionPane.showMessageDialog(frame, "您输入的是: " + inputText, "成功", JOptionPane.INFORMATION_MESSAGE);
}
});
代码解释:

textField.getText(): 返回JTextField中的全部内容,类型为String。inputText.trim().isEmpty(): 一个很好的实践,用于检查用户是否只输入了空格或直接留空。trim()会去除字符串首尾的空格。
监听输入变化 (核心)
JTextField 提供了多种监听器来响应不同的输入事件,最常用的是 DocumentListener。
DocumentListener 允许你在文本被插入、删除或更改时立即得到通知,而无需等待用户点击按钮。
DocumentListener 有三个方法:
insertUpdate(): 当有文本被插入时调用。removeUpdate(): 当有文本被删除时调用。changedUpdate(): 当属性(如字体、颜色)改变时调用,对于普通文本输入,前两个方法最常用。
示例:实时显示字符数

// 在创建 JTextField 后,为其添加 DocumentListener
textField.getDocument().addDocumentListener(new javax.swing.event.DocumentListener() {
@Override
public void insertUpdate(javax.swing.event.DocumentEvent e) {
updateCharCount();
}
@Override
public void removeUpdate(javax.swing.event.DocumentEvent e) {
updateCharCount();
}
@Override
public void changedUpdate(javax.swing.event.DocumentEvent e) {
// 对于普通文本,这个方法通常不会被触发
updateCharCount();
}
private void updateCharCount() {
String text = textField.getText();
// 可以在这里更新一个标签来显示字符数
System.out.println("当前字符数: " + text.length());
}
});
更现代的写法 (使用 Lambda 表达式):
textField.getDocument().addDocumentListener(new javax.swing.event.DocumentListener() {
@Override public void insertUpdate(javax.swing.event.DocumentEvent e) { update(); }
@Override public void removeUpdate(javax.swing.event.DocumentEvent e) { update(); }
@Override public void changedUpdate(javax.swing.event.DocumentEvent e) { update(); }
private void update() {
System.out.println("文本已更新: " + textField.getText());
}
});
限制输入内容
我们希望用户只能输入特定类型的内容,比如数字,有几种方法可以实现:
使用 JFormattedTextField (推荐)
这是最官方、最强大的方式,专门用于格式化输入。
import javax.swing.text.*;
// 创建一个只能输入整数的格式化文本框
JFormattedTextField numberField = new JFormattedTextField(NumberFormat.getIntegerInstance());
numberField.setColumns(10);
// 或者,使用 MaskFormatter 来限制格式,例如电话号码 (###-####)
try {
MaskFormatter phoneFormatter = new MaskFormatter("###-####");
phoneFormatter.setPlaceholderCharacter('_'); // 设置占位符
JFormattedTextField phoneField = new JFormattedTextField(phoneFormatter);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
使用 DocumentFilter (高级、灵活)
如果你想对 JTextField 进行更精细的控制,可以创建一个自定义的 Document 并为其添加 DocumentFilter。
示例:只允许输入数字
// 1. 创建一个普通文本框
JTextField numberOnlyField = new JTextField(15);
// 2. 获取其模型
PlainDocument doc = (PlainDocument) numberOnlyField.getDocument();
// 3. 为模型设置一个自定义的过滤器
try {
doc.setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
// 如果插入的文本全部是数字,则允许插入
if (text.matches("\\d+")) {
super.insertString(fb, offset, text, attr);
}
// 否则,不做任何操作(即忽略输入)
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException {
// 替换操作时,检查要替换的文本是否为数字
if (text.matches("\\d+")) {
super.replace(fb, offset, length, text, attr);
}
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
设置输入提示 (水印)
JTextField 本身没有直接设置水印的属性,但我们可以通过监听焦点事件来实现。
final String placeholder = "请输入用户名...";
JTextField usernameField = new JTextField(20);
// 初始时显示提示文本
usernameField.setText(placeholder);
usernameField.setForeground(Color.GRAY); // 提示文本使用灰色
// 监听焦点事件
usernameField.addFocusListener(new java.awt.event.FocusAdapter() {
@Override
public void focusGained(java.awt.event.FocusEvent evt) {
if (usernameField.getText().equals(placeholder)) {
usernameField.setText("");
usernameField.setForeground(Color.BLACK); // 获得焦点时,文本变黑
}
}
@Override
public void focusLost(java.awt.event.FocusEvent evt) {
if (usernameField.getText().isEmpty()) {
usernameField.setText(placeholder);
usernameField.setForeground(Color.GRAY); // 失去焦点且为空时,恢复提示文本
}
}
});
完整示例代码
下面是一个结合了以上多个知识点的完整示例。
import javax.swing.*;
import javax.swing.event.DocumentListener;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ComprehensiveTextFieldExample {
public static void main(String[] args) {
// 创建主窗口
JFrame frame = new JFrame("JTextField 综合示例");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.setLayout(new BorderLayout(10, 10)); // 使用边界布局
// --- 北部:输入区域 ---
JPanel inputPanel = new JPanel(new GridLayout(3, 2, 5, 5));
inputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
// 1. 普通文本输入
JLabel nameLabel = new JLabel("姓名:");
JTextField nameField = new JTextField(20);
// 2. 数字输入 (使用 DocumentFilter)
JLabel ageLabel = new JLabel("年龄:");
JTextField ageField = new JTextField(10);
setupNumberOnlyFilter(ageField);
// 3. 带水印的输入
JLabel userLabel = new JLabel("用户名:");
JTextField userField = new JTextField(20);
setupPlaceholder(userField, "请输入用户名");
inputPanel.add(nameLabel);
inputPanel.add(nameField);
inputPanel.add(ageLabel);
inputPanel.add(ageField);
inputPanel.add(userLabel);
inputPanel.add(userField);
frame.add(inputPanel, BorderLayout.NORTH);
// --- 中部:实时反馈区域 ---
JPanel feedbackPanel = new JPanel(new FlowLayout());
JLabel charCountLabel = new JLabel("字符数: 0");
feedbackPanel.add(charCountLabel);
frame.add(feedbackPanel, BorderLayout.CENTER);
// --- 南部:按钮区域 ---
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton submitButton = new JButton("提交");
buttonPanel.add(submitButton);
frame.add(buttonPanel, BorderLayout.SOUTH);
// --- 功能实现 ---
// 1. 实时字符计数 (监听 nameField)
nameField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) { update(); }
public void removeUpdate(DocumentEvent e) { update(); }
public void insertUpdate(DocumentEvent e) { update(); }
public void update() {
charCountLabel.setText("字符数: " + nameField.getText().length());
}
});
// 2. 提交按钮事件
submitButton.addActionListener(e -> {
String name = nameField.getText();
String age = ageField.getText();
String user = userField.getText();
// 验证输入
if (name == null || name.trim().isEmpty()) {
JOptionPane.showMessageDialog(frame, "姓名不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
if (age == null || age.trim().isEmpty()) {
JOptionPane.showMessageDialog(frame, "年龄不能为空!", "错误", JOptionPane.ERROR_MESSAGE);
return;
}
// 显示结果
String message = String.format("提交成功!\n姓名: %s\n年龄: %s\n用户名: %s", name, age, user);
JOptionPane.showMessageDialog(frame, message, "信息", JOptionPane.INFORMATION_MESSAGE);
});
// 显示窗口
frame.setVisible(true);
}
/**
* 设置一个文本框只能输入数字
*/
private static void setupNumberOnlyFilter(JTextField field) {
PlainDocument doc = (PlainDocument) field.getDocument();
try {
doc.setDocumentFilter(new DocumentFilter() {
@Override
public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
if (text.matches("\\d+")) {
super.insertString(fb, offset, text, attr);
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException {
if (text.matches("\\d+")) {
super.replace(fb, offset, length, text, attr);
}
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 设置文本框的占位符(水印)
*/
private static void setupPlaceholder(JTextField field, String placeholder) {
field.setText(placeholder);
field.setForeground(Color.GRAY);
field.addFocusListener(new java.awt.event.FocusAdapter() {
@Override
public void focusGained(java.awt.event.FocusEvent evt) {
if (field.getText().equals(placeholder)) {
field.setText("");
field.setForeground(Color.BLACK);
}
}
@Override
public void focusLost(java.awt.event.FocusEvent evt) {
if (field.getText().isEmpty()) {
field.setText(placeholder);
field.setForeground(Color.GRAY);
}
}
});
}
}
| 功能 | 主要方法/技术 | 说明 |
|---|---|---|
| 创建 | new JTextField(columns) |
创建指定宽度的单行文本框。 |
getText() |
在事件监听器中调用,获取用户输入的字符串。 | |
| 监听变化 | document.addDocumentListener() |
实时响应文本的插入、删除等操作,适合做即时验证或反馈。 |
| 限制输入 | JFormattedTextFieldDocumentFilter |
JFormattedTextField 是官方推荐方式,用于数字、日期等格式。DocumentFilter 更灵活,可进行任意复杂的输入过滤。 |
| 输入提示 | FocusListener + setText() |
通过监听焦点事件,动态切换提示文本和用户输入文本。 |
| 事件触发 | addActionListener() |
最常用的事件,通常与“提交”按钮关联,用于在用户完成输入后执行操作。 |
希望这份详细的指南能帮助你完全掌握 Java JTextField 的输入处理!
