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

Java Swing调用setText设置标签文本时出现多余组件如何修复

问题根因

你遇到的组件错位、出现多余重复组件的问题主要由以下几个错误导致:

  • 布局约束绑定错误:给登录面板p内部的组件配置SpringLayout约束时,错误地将参考对象设置为了整个窗口的contentPane,而非p自身。p本身在窗口中已经有(432,155)的偏移量,内部组件再基于整个窗口定位,会导致组件实际渲染位置超出面板范围,调用setText触发界面重绘后布局计算混乱,出现组件错位、重复绘制的问题,视觉上就像多了多余组件。
  • 窗口布局冲突:JFrame默认使用BorderLayout布局,先后调用f.add(p)和f.add(img)时都没有指定布局约束,两个组件都会被放到BorderLayout的CENTER区域,互相叠加产生绘制冲突。
  • 半透明绘制异常:给面板p设置了alpha值仅为5的半透明背景,但没有将面板设置为非不透明(opaque=false),Swing默认不会正确处理半透明容器的绘制,容易产生画面残留。
  • 多余循环加重绘制问题:验证失败的分支里错误使用while循环修改标签文本,单次点击会触发3次文本修改和界面重绘,进一步加重了绘制异常。
  • 尝试计数逻辑错误:计数变量i定义在点击事件方法内部,每次点击登录都会被重置为0,无法实现累计3次尝试的限制逻辑。
  • 废弃API使用:JPasswordField.getText()方法已被官方废弃,存在安全风险,应当使用getPassword()获取密码字符数组后再转字符串比较。
修复步骤
  1. 调整SpringLayout约束的参考对象为面板p自身,同步调整约束数值适配面板的400*450尺寸。
  2. 调整背景图和面板的层级:将背景图img作为窗口底层组件,再将登录面板p设置为透明,叠加在背景图上层。
  3. 给面板p添加setOpaque(false)配置,保证半透明效果正确渲染。
  4. 去掉无用的while循环,将计数变量i改为类的成员变量,实现累计计数,达到3次尝试后锁定登录按钮。
  5. 替换废弃的密码获取API,同时保证Swing组件在事件分发线程初始化避免线程安全问题。
修复后完整代码
import java.awt.*;
import java.awt.Font;
import javax.swing.*;
import java.awt.event.*;

public class LoginGUI implements ActionListener{
    
    //Variables
    JTextField tField1, tField2;
    JPasswordField pwField;
    JButton btn1, btn2;
    JLabel label1, label2, label3, label4;
    private ImageIcon bgImage;
    private JLabel img;
    simpleCal Calculator;
    // 登录尝试计数改为成员变量实现累计计数
    int attemptCount = 0;
    int maxAttempt = 3;
    
    public LoginGUI(){
        //Layout
        SpringLayout layout = new SpringLayout();
        bgImage = new ImageIcon(this.getClass().getResource("/assets/loginBG.png"));
        img = new JLabel(bgImage);
        JFrame f = new JFrame("Login");
        f.setSize(1280,800);
        // 把背景图设为内容面板,后续组件直接叠加在背景上
        f.setContentPane(img);
        f.setLayout(new BorderLayout());
        
        JPanel p = new JPanel();
        p.setLayout(layout);
        p.setPreferredSize(new Dimension(400,450));
        p.setBackground(new Color(101,168,223,5));
        // 设置面板非不透明,解决半透明绘制异常问题
        p.setOpaque(false);
        f.add(p, BorderLayout.CENTER);
        
        //Fonts
        Font font1 = new Font("calibri",Font.BOLD,20);
        Font font2 = new Font("calibri",Font.BOLD,14);
        
        //Label
        label1 = new JLabel("Username:");
        label1.setFont(font1);
        label1.setForeground(new Color(55,55,55));
        // 约束参考改为面板p自身
        layout.putConstraint(layout.WEST, label1, 50, layout.WEST, p);
        layout.putConstraint(layout.NORTH, label1, 130, layout.NORTH, p);
        
        label2 = new JLabel("Password:");
        label2.setFont(font1);
        label2.setForeground(new Color(55,55,55));
        layout.putConstraint(layout.WEST, label2, 50, layout.WEST, p);
        layout.putConstraint(layout.NORTH, label2, 30, layout.SOUTH, label1);
        
        label3 = new JLabel("");
        label3.setFont(font1);
        label3.setForeground(new Color(55,55,55));
        layout.putConstraint(layout.WEST, label3, 70, layout.WEST, p);
        layout.putConstraint(layout.NORTH, label3, 40, layout.NORTH, p);
        
        
        label4 = new JLabel("");
        label4.setFont(font1);
        label4.setForeground(new Color(55,55,55));
        layout.putConstraint(layout.WEST, label4, 105, layout.WEST, p);
        layout.putConstraint(layout.NORTH, label4, 20, layout.SOUTH, label3);
        
        
        //TextField
        tField1 = new JTextField("");
        tField1.setFont(font2);
        tField1.setColumns(15);
        tField1.setBackground(new Color(101,168,223));
        layout.putConstraint(layout.WEST, tField1, 40, layout.EAST, label1);
        layout.putConstraint(layout.NORTH, tField1, 130, layout.NORTH, p);
        
        //PasswordField
        pwField = new JPasswordField();
        pwField.setFont(font2);
        pwField.setColumns(15);
        pwField.setBackground(new Color(101,168,223));
        layout.putConstraint(layout.WEST, pwField, 43, layout.EAST, label2);
        layout.putConstraint(layout.NORTH, pwField, 30, layout.SOUTH, tField1);
        
        //Button
        btn1 = new JButton("Log in");
        btn1.setFont(font1);
        btn1.setSize(100,50);
        btn1.addActionListener(this);
        p.add(btn1);
        layout.putConstraint(layout.WEST, btn1, 80, layout.WEST, p);
        layout.putConstraint(layout.NORTH, btn1, 250, layout.NORTH, p);
        
        p.add(label3);
        p.add(label4);
        p.add(tField1);
        p.add(pwField);
        p.add(label1);
        p.add(label2);
        
        f.setVisible(true);
        f.setResizable(false);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    
    public void actionPerformed(ActionEvent e){
        String user, pass;
        
        if(e.getSource()==btn1){
            user = tField1.getText();
            // 替换废弃的getText方法
            pass = new String(pwField.getPassword());
            
            if(user.equals("vince")&&pass.equals("123")){
                Calculator = new simpleCal();
                // 登录成功后可主动关闭登录窗口
                // ((JFrame)SwingUtilities.getWindowAncestor(btn1)).dispose();
            }
            else{
                attemptCount++;
                label3.setText("登录凭据错误");
                label4.setText("尝试次数: " + attemptCount);
                if(attemptCount >= maxAttempt){
                    btn1.setEnabled(false);
                    label3.setText("尝试次数过多,登录已锁定");
                }
            }
        }
        
    }
    
    public static void main(String[]args){
        // 保证Swing组件在事件分发线程初始化,避免线程安全问题
        SwingUtilities.invokeLater(() -> new LoginGUI());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:54:03