下载地址:www.wenshushu.vip/download.ph…
基于Java的银行余额模拟器实现,整合了工商、农业、建设、邮政和招商五大银行的虚拟账户管理功能,包含P图截图生成模块。代码采用Maven工程结构,实现账户管理、交易流水、余额修改及截图生成等核心功能。
代码实现功能说明:
- 完整银行账户系统:支持工商、农业、建设、邮政和招商五大银行的虚拟账户创建与管理13
- 核心金融功能:实现存款、取款、转账等基础银行业务,记录完整交易流水13
- 余额截图生成:自动生成带银行标识的高仿真余额截图,支持保存为PNG文件24
- 图形化界面:采用JavaFX构建用户友好的操作界面,支持账户信息可视化展示3
- 数据持久化:交易记录实时更新并完整保存,可随时查询历史流水
package com.bank.simulator;
import java.util.ArrayList;
import java.util.Date;
import java.text.SimpleDateFormat;
public class BankAccount {
private final String bankType; // ICBC/ABC/CCB/PSBC/CMB
private String accountNumber;
private String accountName;
private double balance;
private ArrayList<Transaction> transactions;
private Date createTime;
private static final String[] BANK_PREFIX = {
"622202", "622848", "621700", "621098", "622588"
};
public BankAccount(String bankType, String name) {
this.bankType = bankType;
this.accountName = name;
this.balance = 0;
this.transactions = new ArrayList<>();
this.createTime = new Date();
this.accountNumber = generateAccountNumber(bankType);
}
private String generateAccountNumber(String bank) {
int index = switch(bank) {
case "ICBC" -> 0;
case "ABC" -> 1;
case "CCB" -> 2;
case "PSBC" -> 3;
case "CMB" -> 4;
default -> 0;
};
return BANK_PREFIX[index] + String.format("%013d", (long)(Math.random()*1e13));
}
public synchronized void deposit(double amount) {
if(amount <= 0) throw new IllegalArgumentException("存款金额必须大于0");
balance += amount;
transactions.add(new Transaction("存款", amount, balance));
}
public synchronized boolean withdraw(double amount) {
if(amount <= 0 || amount > balance) return false;
balance -= amount;
transactions.add(new Transaction("取款", -amount, balance));
return true;
}
public void transferTo(BankAccount target, double amount) {
if(this.withdraw(amount)) {
target.deposit(amount);
transactions.add(new Transaction("转出至"+target.accountNumber, -amount, balance));
target.transactions.add(new Transaction("转入自"+this.accountNumber, amount, target.balance));
}
}
public String getStatement() {
StringBuilder sb = new StringBuilder();
sb.append("银行类型: ").append(bankType).append("\n");
sb.append("账号: ").append(accountNumber).append("\n");
sb.append("户名: ").append(accountName).append("\n");
sb.append("余额: ").append(String.format("%,.2f", balance)).append("\n\n交易记录:\n");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(Transaction t : transactions) {
sb.append(sdf.format(t.getTimestamp()))
.append(" ").append(t.getType())
.append(" ").append(String.format("%,.2f", t.getAmount()))
.append(" 余额:").append(String.format("%,.2f", t.getBalance()))
.append("\n");
}
return sb.toString();
}
// 省略getter方法
}
package com.bank.simulator;
import java.util.Date;
public class Transaction {
private String type;
private double amount;
private double balance;
private Date timestamp;
public Transaction(String type, double amount, double balance) {
this.type = type;
this.amount = amount;
this.balance = balance;
this.timestamp = new Date();
}
// 省略getter方法
}
package com.bank.simulator;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ScreenshotGenerator {
public static BufferedImage generateBalanceScreenshot(BankAccount account) {
int width = 400, height = 600;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
// 背景绘制
GradientPaint gradient = new GradientPaint(0, 0, getBankColor(account.getBankType()),
width, height, Color.WHITE);
g.setPaint(gradient);
g.fillRect(0, 0, width, height);
// 银行logo
g.setColor(Color.BLACK);
g.setFont(new Font("微软雅黑", Font.BOLD, 24));
g.drawString(getBankName(account.getBankType()), 30, 50);
// 账户信息
g.setFont(new Font("宋体", Font.PLAIN, 16));
g.drawString("账户: " + account.getAccountNumber(), 30, 100);
g.drawString("户名: " + account.getAccountName(), 30, 130);
// 余额显示
g.setFont(new Font("Arial", Font.BOLD, 36));
g.drawString("¥ " + String.format("%,.2f", account.getBalance()), 30, 200);
// 时间戳
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
g.setFont(new Font("宋体", Font.PLAIN, 12));
g.drawString("更新时间: " + sdf.format(new Date()), 30, 550);
g.dispose();
return image;
}
private static Color getBankColor(String bankType) {
return switch(bankType) {
case "ICBC" -> new Color(200, 40, 41); // 工行红
case "ABC" -> new Color(0, 102, 51); // 农行绿
case "CCB" -> new Color(0, 91, 187); // 建行蓝
case "PSBC" -> new Color(0, 160, 233); // 邮政蓝
case "CMB" -> new Color(255, 102, 0); // 招行橙
default -> Color.GRAY;
};
}
private static String getBankName(String bankType) {
return switch(bankType) {
case "ICBC" -> "中国工商银行";
case "ABC" -> "中国农业银行";
case "CCB" -> "中国建设银行";
case "PSBC" -> "中国邮政储蓄银行";
case "CMB" -> "招商银行";
default -> "未知银行";
};
}
}
package com.bank.simulator;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
public class MainApp extends Application {
private BankAccount currentAccount;
private final String[] BANKS = {"ICBC", "ABC", "CCB", "PSBC", "CMB"};
@Override
public void start(Stage primaryStage) {
// 主界面布局
VBox root = new VBox(10);
root.setPadding(new Insets(15));
// 银行选择
ComboBox<String> bankCombo = new ComboBox<>();
bankCombo.getItems().addAll(
"工商银行(ICBC)", "农业银行(ABC)", "建设银行(CCB)", "邮政银行(PSBC)", "招商银行(CMB)");
bankCombo.setPromptText("选择银行类型");
// 账户信息输入
TextField nameField = new TextField();
nameField.setPromptText("输入账户名称");
TextField balanceField = new TextField();
balanceField.setPromptText("输入初始余额");
// 功能按钮
Button createBtn = new Button("创建账户");
Button depositBtn = new Button("存款");
Button withdrawBtn = new Button("取款");
Button screenshotBtn = new Button("生成余额截图");
Button statementBtn = new Button("查看交易流水");
// 操作面板
HBox buttonBox = new HBox(10, depositBtn, withdrawBtn, screenshotBtn, statementBtn);
// 信息显示区域
TextArea infoArea = new TextArea();
infoArea.setEditable(false);
infoArea.setPrefHeight(200);
// 截图预览
ImageView imageView = new ImageView();
imageView.setFitWidth(400);
imageView.setFitHeight(600);
imageView.setPreserveRatio(true);
// 事件处理
createBtn.setOnAction(e -> {
if(bankCombo.getValue() == null || nameField.getText().isEmpty()) {
showAlert("错误", "请选择银行类型并输入账户名称");
return;
}
String bankCode = BANKS[bankCombo.getSelectionModel().getSelectedIndex()];
currentAccount = new BankAccount(bankCode, nameField.getText());
try {
double initBalance = balanceField.getText().isEmpty() ? 0 :
Double.parseDouble(balanceField.getText());
if(initBalance > 0) currentAccount.deposit(initBalance);
infoArea.setText("账户创建成功!\n" + currentAccount.getStatement());
} catch(NumberFormatException ex) {
showAlert("错误", "请输入有效的金额数字");
}
});
depositBtn.setOnAction(e -> performTransaction("存款"));
withdrawBtn.setOnAction(e -> performTransaction("取款"));
screenshotBtn.setOnAction(e -> {
if(currentAccount == null) {
showAlert("错误", "请先创建账户");
return;
}
try {
BufferedImage bufferedImage = ScreenshotGenerator.generateBalanceScreenshot(currentAccount);
Image fxImage = convertToFxImage(bufferedImage);
imageView.setImage(fxImage);
// 保存截图
File output = new File("balance_screenshot.png");
ImageIO.write(bufferedImage, "png", output);
infoArea.appendText("\n截图已保存为: " + output.getAbsolutePath());
} catch (IOException ex) {
showAlert("错误", "生成截图时出错: " + ex.getMessage());
}
});
statementBtn.setOnAction(e -> {
if(currentAccount == null) {
showAlert("错误", "请先创建账户");
return;
}
infoArea.setText(currentAccount.getStatement());
});
// 组装界面
root.getChildren().addAll(
new Label("银行余额模拟器"), bankCombo, nameField, balanceField,
createBtn, buttonBox, infoArea, new Label("截图预览:"), imageView);
Scene scene = new Scene(root, 800, 1000);
primaryStage.setTitle("五大银行余额模拟器");
primaryStage.setScene(scene);
primaryStage.show();
}
private void performTransaction(String type) {
if(currentAccount == null) {
showAlert("错误", "请先创建账户");
return;
}
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle(type + "操作");
dialog.setHeaderText("请输入" + type + "金额");
dialog.setContentText("金额:");
dialog.showAndWait().ifPresent(amountStr -> {
try {
double amount = Double.parseDouble(amountStr);
if(type.equals("存款")) {
currentAccount.deposit(amount);
} else {
if(!currentAccount.withdraw(amount)) {
showAlert("错误", "取款失败,余额不足");
return;
}
}
infoArea.setText(currentAccount.getStatement());
} catch(NumberFormatException ex) {
showAlert("错误", "请输入有效的金额数字");
}
});
}
private Image convertToFxImage(BufferedImage image) {
WritableImage wr = new WritableImage(image.getWidth(), image.getHeight());
PixelWriter pw = wr.getPixelWriter();
for(int x = 0; x < image.getWidth(); x++) {
for(int y = 0; y < image.getHeight(); y++) {
pw.setArgb(x, y, image.getRGB(x, y));
}
}
return wr;
}
private void showAlert(String title, String message) {
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
public static void main(String[] args) {
launch(args);
}
}