You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Swing工件尺寸输入框问题排查与优化方案咨询

问题解决与优化方案

先解决你当前的两个核心问题

问题原因分析

你遇到的两个问题本质上是同一个逻辑顺序错误导致的:
在按钮点击事件中,你先执行了Integer.parseInt(),如果输入框为空,这个方法会直接抛出NumberFormatException,导致后续的空判断代码根本没机会运行,同时因为没有捕获这个异常,控制台就会输出大量错误栈信息。

修改后的按钮点击事件代码

btnPrfeDieAngaben.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // 先清空之前的提示
        leeresFeld.setText("");
        
        // 获取输入文本并去除首尾空格
        String heightText = Feld1.getText().trim();
        String widthText = Feld2.getText().trim();
        String lengthText = Feld3.getText().trim();
        
        // 优先检查是否有空输入
        if (heightText.isEmpty() || widthText.isEmpty() || lengthText.isEmpty()) {
            leeresFeld.setText("Please fill in all fields!");
            return;
        }
        
        int answer1, answer2, answer3;
        try {
            // 安全解析数字(加兜底异常捕获)
            answer1 = Integer.parseInt(heightText);
            answer2 = Integer.parseInt(widthText);
            answer3 = Integer.parseInt(lengthText);
        } catch (NumberFormatException ex) {
            // 理论上因按键过滤不会走到这里,但留个兜底逻辑
            leeresFeld.setText("Please enter valid numbers only!");
            return;
        }
        
        // 检查数值范围
        if (answer1 >= 1 && answer1 <= 150 
            && answer2 >= 1 && answer2 <= 150 
            && answer3 >= 1 && answer3 <= 150) {
            leeresFeld.setText("You entered: " + heightText + " , " + widthText + " , " + lengthText + " mm");
        } else {
            ImageIcon iconic = new ImageIcon(Machine_LearningApp.class.getResource("x-taste.png"));
            // 改用WARNING_MESSAGE更符合警告场景
            JOptionPane.showMessageDialog(null, "Enter only numbers between 1 and 150 mm!", "Warning", JOptionPane.WARNING_MESSAGE, iconic);
        }
    }
});

更优实现方式建议

除了修复当前问题,还有几个可以提升代码质量和用户体验的优化点:

1. 替换Null布局为布局管理器

你现在用的setLayout(null)+手动设置bounds的方式,会导致界面在不同分辨率、窗口大小变化时完全错乱。推荐使用BorderLayout、GridBagLayout或者GroupLayout,结合JPanel嵌套不同布局,让界面自适应各种场景。

2. 复用重复的按键监听逻辑

三个输入框的按键监听代码完全一致,可以提取成单独实例避免重复:

KeyAdapter numberKeyAdapter = new KeyAdapter() {
    @Override
    public void keyTyped(KeyEvent e) {
        char c = e.getKeyChar();
        if (!(Character.isDigit(c) || c == KeyEvent.VK_BACK_SPACE || c == KeyEvent.VK_DELETE)) {
            e.consume();
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        leeresFeld.setText(""); // 直接清空比设空格更合理
    }
};
// 给三个输入框绑定同一个监听
Feld1.addKeyListener(numberKeyAdapter);
Feld2.addKeyListener(numberKeyAdapter);
Feld3.addKeyListener(numberKeyAdapter);

3. 使用InputVerifier实现即时输入验证

相比在按钮点击时统一验证,InputVerifier可以在用户离开输入框时即时提示错误,提升用户体验:

InputVerifier numberRangeVerifier = new InputVerifier() {
    @Override
    public boolean verify(JComponent input) {
        JTextField tf = (JTextField) input;
        String text = tf.getText().trim();
        if (text.isEmpty()) {
            leeresFeld.setText("This field cannot be empty!");
            return false;
        }
        try {
            int num = Integer.parseInt(text);
            if (num < 1 || num > 150) {
                leeresFeld.setText("Please enter a number between 1 and 150!");
                return false;
            }
        } catch (NumberFormatException ex) {
            leeresFeld.setText("Please enter a valid number!");
            return false;
        }
        leeresFeld.setText("");
        return true;
    }
};
// 绑定到输入框
Feld1.setInputVerifier(numberRangeVerifier);
Feld2.setInputVerifier(numberRangeVerifier);
Feld3.setInputVerifier(numberRangeVerifier);

4. 使用DocumentFilter彻底限制输入内容

按键监听无法阻止用户通过粘贴输入非数字,DocumentFilter可以从根本上限制文本框只能输入数字:

class NumberDocumentFilter extends DocumentFilter {
    @Override
    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
        if (string.matches("\\d*")) { // 只允许输入数字
            super.insertString(fb, offset, string, attr);
        }
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
        if (text.matches("\\d*")) {
            super.replace(fb, offset, length, text, attrs);
        }
    }
}
// 给输入框设置过滤器
((AbstractDocument) Feld1.getDocument()).setDocumentFilter(new NumberDocumentFilter());
((AbstractDocument) Feld2.getDocument()).setDocumentFilter(new NumberDocumentFilter());
((AbstractDocument) Feld3.getDocument()).setDocumentFilter(new NumberDocumentFilter());

5. 组件命名规范化

把Feld1、Feld2改成heightField、widthField这类有语义的名称,代码可读性和维护性会大幅提升。

内容的提问来源于stack exchange,提问作者f_ozk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:07:58