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

Java银行应用中JLabel设置文本不生效问题求助

银行应用余额查询JLabel不显示问题解决

问题描述

开发支持开户、存转取及余额查询的银行应用时,余额查询模块出现异常:点击“Show balance”按钮打开余额窗口后,界面上的JLabel未显示用户余额。已确认数据库连接正常,修改JLabel文本、调整SQL语句均无效,balance.setText()看似未生效。

相关代码

Java代码

package app;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import java.sql.*;

public class ViewBalance extends JFrame {

    private JLabel mainl, balance;
    private JButton ok;
    ResultSet result = null;

    public ViewBalance(Statement statement, int accnum) { //accnum is the account number that was just created
        super("Banking Application");

        mainl = new JLabel("Balance", SwingConstants.CENTER);
        balance = new JLabel("", SwingConstants.CENTER);
        ok = new JButton("Ok");
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    result = statement.executeQuery("SELECT balance FROM CardInfo WHERE accnum = " + accnum + ";");
                    if (result.next()) {
                        System.out.println(result.getInt(1));
                        balance.setText("Your balance is " + result.getInt(1));
                        balance.setVisible(true); 
                    }
                } catch (SQLException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                dispose();
                new MainFrame(statement, accnum).setVisible(true);
            }
        });

        add(mainl, BorderLayout.NORTH);
        add(balance, BorderLayout.CENTER);
        add(ok, BorderLayout.SOUTH);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
}

SQL代码

DROP DATABASE IF EXISTS BankingApplication;
DROP TABLE IF EXISTS CardInfo CASCADE;
DROP TABLE IF EXISTS AccountInfo CASCADE;

CREATE DATABASE BankingApplication
    WITH
    OWNER = postgres
    ENCODING = 'UTF8'
    LC_COLLATE = 'English_United States.1253'
    LC_CTYPE = 'English_United States.1253'
    TABLESPACE = pg_default
    CONNECTION LIMIT = -1
    IS_TEMPLATE = False;
    
CREATE TABLE AccountInfo(
    accnum INT,
    fname varchar(100),
    lname varchar(100),
    mobile varchar(10),
    id varchar(20),
    ssn varchar(9),
    address varchar(100),
    email varchar(100),
    password varchar(100),
    primary key(accnum)
);

CREATE TABLE CardInfo(
    accnum int,
    cardnum varchar(16),
    expmonth int,
    expyear int,
    cvv int,
    pin int,
    balance float,
    primary key(cardnum),
    FOREIGN KEY (accnum) REFERENCES AccountInfo (accnum)
);

SELECT * FROM AccountInfo;
SELECT * FROM CardInfo;

效果对比

  • 预期:窗口显示Your balance is [具体金额]
  • 实际:JLabel无内容显示

问题根源

  1. 逻辑流程错误:余额查询逻辑放在Ok按钮的点击事件中,查询完成后立即销毁当前窗口并返回主界面,用户根本没有机会看到更新后的JLabel内容。正确逻辑应为窗口初始化时就查询并显示余额,Ok按钮仅负责关闭窗口。
  2. SQL注入风险:直接拼接accnum参数到SQL语句中,存在安全隐患。
  3. 类型不匹配:数据库中balance是float类型,使用getInt()会丢失小数精度。

解决方案

修正后的完整Java代码

package app;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import java.sql.*;

public class ViewBalance extends JFrame {

    private JLabel mainl, balance;
    private JButton ok;

    public ViewBalance(Statement statement, int accnum) {
        super("Banking Application");

        mainl = new JLabel("Balance", SwingConstants.CENTER);
        balance = new JLabel("", SwingConstants.CENTER);
        ok = new JButton("Ok");
        
        // 窗口初始化时执行余额查询
        try {
            // 使用PreparedStatement避免SQL注入
            String sql = "SELECT balance FROM CardInfo WHERE accnum = ?";
            PreparedStatement pstmt = statement.getConnection().prepareStatement(sql);
            pstmt.setInt(1, accnum);
            ResultSet result = pstmt.executeQuery();
            
            if (result.next()) {
                float balanceVal = result.getFloat(1);
                balance.setText("Your balance is " + balanceVal);
            } else {
                balance.setText("No account found");
            }
            // 关闭数据库资源,防止泄漏
            result.close();
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
            balance.setText("Failed to load balance");
            JOptionPane.showMessageDialog(this, "查询失败:" + e.getMessage());
        }
        
        // Ok按钮仅负责关闭窗口返回主界面
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                dispose();
                new MainFrame(statement, accnum).setVisible(true);
            }
        });

        add(mainl, BorderLayout.NORTH);
        add(balance, BorderLayout.CENTER);
        add(ok, BorderLayout.SOUTH);

        pack();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }
}

额外优化建议

  • 使用SwingWorker将数据库操作放在后台线程执行,避免阻塞UI线程导致界面卡顿。
  • 统一异常处理,给用户更友好的错误提示。
  • 确保所有数据库资源(ResultSet、Statement、Connection)都被正确关闭。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:35:01