项目完整代码及运行结果见团队博客:
购买彩票抽奖系统(团队版)-CSDN博客
git链接:LotterySystem: 这里是抽奖系统
个人负责部分有:
图形化界面,彩票信息记录,用户注册登录,用户名、密码余额等信息管理,用户抽奖功能
(一)GUI:
该类可以说是整个系统菜单,与各个包都有紧密的联系
RegisterGUI
// 注册按钮点击事件
registerButton.addActionListener(e -> {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
String telnumber = telField.getText();
int r = DataStorage.register(username, password, telnumber, userRecords);
if (r == 0) {
JOptionPane.showMessageDialog(frame, "该用户名已被注册,请选择其他用户名。");
} else if (r == -1) {
JOptionPane.showMessageDialog(frame, "密码必须为6位,请重新输入。");
} else if (r == 1) {
JOptionPane.showMessageDialog(frame, "注册成功!");
frame.dispose();
new LoginGUI();
}
});
frame.setVisible(true);
}
LoginGUI 类
// 创建“买前需知”按钮
JButton infoButton = new JButton("买前需知");
infoButton.setOpaque(false);
infoButton.setContentAreaFilled(false);
infoButton.setBorderPainted(false);
// 将“买前需知”按钮添加到 layeredPane 中,并设置其位置在右上角
infoButton.setBounds(250, 10, 100, 30);
layeredPane.add(infoButton, JLayeredPane.PALETTE_LAYER);
// 为“买前需知”按钮添加点击事件监听器
infoButton.addActionListener(e -> {
// 在这里添加点击按钮后的操作,例如显示一个对话框
JOptionPane.showMessageDialog(frame, """
这里是买前需知的信息。
1. 购买“36选7”时,由购买者从01-36共36个号码中选取7个码为基本号码进行投注。
单张彩票复式最大投注数量限1注。
2. 共设4个奖级,即特、一、二、三等奖。
3. 奖金分配:特等奖固定奖金为1000元。一等奖固定奖金为500元。二等奖固定奖金为250元。三等奖固定奖金为100元。
4. 所购彩票与开奖结果对照,符合以下情况即为中奖。
特等奖: 选中7个基本号码;
一等奖: 选中6个基本号码;
二等奖: 选中5个基本号码;
三等奖: 选中4个基本号码""");
});
// 登录按钮点击事件
loginButton.addActionListener(e -> {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
if (userMode.isSelected()) {
currentUser = DataStorage.loginUser(username, password, userRecords);
if (currentUser != null) {
JOptionPane.showMessageDialog(frame, "登录成功!");
frame.dispose();
new UserGUI(currentUser);
} else {
JOptionPane.showMessageDialog(frame, "登录失败!请检查用户名和密码。");
}
} else if (adminMode.isSelected()) {
if (Admin.validateAdmin(username, password)) {
JOptionPane.showMessageDialog(frame, "管理员登录成功!");
frame.dispose();
new AdminGUI();
} else {
JOptionPane.showMessageDialog(frame, "管理员用户名或密码错误!");
}
}
});
// 注册按钮点击事件
registerButton.addActionListener(e -> {
frame.dispose();
new RegisterGUI();
});
UserGUI 类
JButton rechargeButton = new JButton("充值");
JButton playButton = new JButton("选择号码");
JButton infoButton = new JButton("查看号码");
// 添加修改信息按钮
JButton modifyInfoButton = new JButton("修改信息");
balanceLabel = new JLabel("余额:" + currentUser.getBalance());
balanceLabel.setOpaque(false);
numbers = NumbersRecord.fileToList(currentUser.getUsername());
Winning.notifyFirstLogin(numbers, currentUser, userRecords, balanceLabel);
buttonPanel.add(rechargeButton);
buttonPanel.add(playButton);
buttonPanel.add(infoButton);
buttonPanel.add(modifyInfoButton);
// 添加修改信息按钮到面板
buttonPanel.add(balanceLabel);
// 将余额标签添加到按钮面板
// 将按钮面板添加到 JLayeredPane 上
buttonPanel.setBounds(50, 50, 300, 200);
// 修改大小以适应新的余额标签
layeredPane.add(buttonPanel, JLayeredPane.PALETTE_LAYER);
frame.add(layeredPane, BorderLayout.CENTER);
// 添加 JLayeredPane 到 frame
// 充值按钮点击事件
rechargeButton.addActionListener(e -> {
String amountStr = JOptionPane.showInputDialog("请输入充值金额");
double amount = Double.parseDouble(amountStr);
currentUser.recharge(currentUser, amount, userRecords);
balanceLabel.setText("余额:" + currentUser.getBalance());
JOptionPane.showMessageDialog(frame, "充值成功,当前余额为:" + currentUser.getBalance());
});
// 选择号码按钮点击事件
playButton.addActionListener(e -> {
String numberOfBets = JOptionPane.showInputDialog("投注数:");
int bets = Integer.parseInt(numberOfBets);
List<String> newNumbers = new ArrayList<>();
while (bets != 0) {
String[] options = {"手动选号", "随机选号"};
int choice = JOptionPane.showOptionDialog(null, "请选择选号方式", "选号",
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
null, options, options[0]);
String number = null;
switch (choice) {
case 0: // 手动选号
number = JOptionPane.showInputDialog("请输入号码");
break;
case 1: // 随机选号
number = NumberSelection.selectNumberRandomly();
break;
default:
break;
}
if (NumberSelection.selectNumber(currentUser, number, numbers) != null) {
newNumbers.add(number);
bets--;
balanceLabel.setText("余额:" + currentUser.getBalance());
if (currentUser.getBalance() < 2.0 && bets != 0) {
JOptionPane.showMessageDialog(null, "余额不足,请先充值");
break;
}
} else {
break;
}
}
// 把新买的彩票保存到文件里,并更新numbers列表
NumbersRecord.addNumberstoList(numbers, newNumbers);
NumbersRecord.saveNumbersToFile(currentUser.getUsername(), newNumbers);
DataStorage.updateBalance(currentUser.getUsername(), currentUser.getBalance(), userRecords);
});
// 查看号码按钮点击事件
infoButton.addActionListener(e -> Show.displayNumbers(numbers, currentUser));
// 修改信息按钮点击事件
modifyInfoButton.addActionListener(e -> {
new ModifyInfoUI(currentUser, balanceLabel,userRecords); // 跳转到修改信息界面
});
AdminGUI 类
JButton setWinningNumberButton = new JButton("手动设置中奖号码");
JButton autoRollingButton = new JButton("自动设置中奖号码");
buttonPanel.add(setWinningNumberButton);
buttonPanel.add(autoRollingButton);
// 将按钮面板添加到 JLayeredPane 上
buttonPanel.setBounds(50, 50, 300, 100);
// 设置按钮面板的位置和大小
layeredPane.add(buttonPanel, JLayeredPane.PALETTE_LAYER);
frame.add(layeredPane, BorderLayout.CENTER);
// 添加 JLayeredPane 到 frame
// 手动设置中奖号码按钮点击事件
setWinningNumberButton.addActionListener(e -> {
String winningNumber = JOptionPane.showInputDialog("请输入中奖号码:");
if (Rolling.setWinningNumber(winningNumber)) {
Show.displayWinnerInfos(Winning.checkWinning(userRecords, winningNumber), winningNumber);
}
});
// 自动设置中奖号码按钮点击事件
autoRollingButton.addActionListener(e -> Rolling.createJframe(userRecords));
学习内容:
创建JFrame 框架类的窗体对象frame变量
使用JButton组件定义并创建按钮:登录、注册、充值、选择号码、查看号码、管理员选项以及指定实例
使用JPanel创建菜单面板buttonPanel,设置面板参数,并将以上按钮放入菜单面板中
对点击后的各个按钮进行动作监听,此时用到JOptionPane类,进行弹窗设置,设置确认型弹窗进行信息的确认,选择型弹窗进行选项的选择
(二)用文件存储数据,记录彩票信息
addNumberstoList:添加号码到列表
saveNumbersToFile:保存号码到文件
fileToList:从文件读取号码
listToFile:将列表写回到文件
public static void addNumberstoList(List<String> numbers, List<String> newNumbers) {
for (String newNumber : newNumbers) {
numbers.add(newNumber + "," + "未中奖");
}
}
// 将新彩票保存到对应用户的彩票文件中
public static void saveNumbersToFile(String username, List<String> newNumbers) {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(username + NUMBER_RECORDS_FILE, true))) {
for (String newNumber : newNumbers) {
writer.write(newNumber + "," + "未中奖");
writer.newLine();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while saving numbers to file", e);
}
}
// 将彩票信息从文件中读到List
public static List<String> fileToList(String username) {
List<String> numbers = new ArrayList<>();
try {
String path = username + NUMBER_RECORDS_FILE;
BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInputStream(path), StandardCharsets.UTF_8));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
numbers.add(line);
}
reader.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while reading numbers from file", e);
}
return numbers;
}
// 将彩票信息从List中读到文件,并覆盖原有内容
public static void listToFile(List<String> numbers, String username) {
try {
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(username + NUMBER_RECORDS_FILE), StandardCharsets.UTF_8));
for (String number : numbers) {
writer.write(number);
writer.newLine();
}
writer.close();
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while writing numbers to file", e);
}
}
(三)用户登录、充值并购买彩票
登录
public static List<String> readUserRecrods() {
List<String> userRecords = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(USER_FILE))) {
String line;
while ((line = reader.readLine()) != null) {
userRecords.add(line);
}
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while reading user records", e);
}
return userRecords;
}
// 登录用户
public static User loginUser(String username, String password, List<String> userRecords) {
for (String record : userRecords) {
String[] parts = record.split(",");
if (parts[0].equals(username) && parts[1].equals(password)) {
return new User(parts[0], parts[1], Double.parseDouble(parts[2]), parts[3]);
}
}
return null;
}
// 注册用户
public static int register(String username, String password, String telnumber, List<String> userRecords) {
if (password.length() < 6) {
return -1;
// 密码必须为6位
}
for (String record : userRecords) {
if (record.startsWith(username + ",")) {
return 0;
// 用户名已存在
}
}
// 追加新用户到文件
try (BufferedWriter writer = new BufferedWriter(new FileWriter(USER_FILE, true))) {
writer.write(username + "," + password + "," + 0.0 + "," + telnumber);
writer.newLine();
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while registering user", e);
return -2;
// 注册失败
}
return 1;
// 注册成功
}
public static void updateBalance(String username, double balance, List<String> userRecords) {
List<String> updatedRecords = new ArrayList<>();
for (String record : userRecords) {
String[] parts = record.split(",");
if (parts[0].equals(username)) {
updatedRecords.add(username + "," + parts[1] + "," + balance + "," + parts[3]);
} else {
updatedRecords.add(record);
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(USER_FILE))) {
for (String record : updatedRecords) {
writer.write(record);
writer.newLine();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while updating user balance", e);
}
}
// 添加 updatePassword 方法
public static void updatePassword(String username, String password, List<String> userRecords) {
List<String> updatedRecords = new ArrayList<>();
for (String record : userRecords) {
String[] parts = record.split(",");
if (parts[0].equals(username)) {
updatedRecords.add(username + "," + password + "," + parts[2] + "," + parts[3]);
} else {
updatedRecords.add(record);
}
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(USER_FILE))) {
for (String record : updatedRecords) {
writer.write(record);
writer.newLine();
}
} catch (IOException e) {
logger.log(Level.SEVERE, "IOException occurred while updating user password", e);
}
}
充值和购买彩票
recharge 增加并更新保存余额
public void recharge(User user, double amount, List<String> userRecords) {
user.setBalance(user.getBalance() + amount);
DataStorage.updateBalance(user.getUsername(), user.getBalance(), userRecords);
System.out.println("充值成功!当前余额为:" + user.getBalance());
}
selectNumberRandomly生成随机数
selectNumber验证并选择用户输入的号码
isValidNumber验证号码是否合法
public static String selectNumberRandomly() {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 7; i++) {
int number = random.nextInt(36) + 1;
sb.append(String.format("%02d", number));
// 使用两位宽度格式化数字,并在前面补0
}
return sb.toString();
}
public static String selectNumber(User user, String number, List<String> numbers) {
double price = 10.0;
// 彩票价格
if (user.getBalance() < price) {
JOptionPane.showMessageDialog(null, "余额不足,请先充值");
return null;
}
if (!isValidNumber(number)) {
JOptionPane.showMessageDialog(null, "号码不合法,请重新选择");
return null;
}
if (numbers.contains(number)) {
JOptionPane.showMessageDialog(null, "号码重复,请重新选择");
return null;
}
user.setBalance(user.getBalance() - price);
// 扣除购买彩票的金额
JOptionPane.showMessageDialog(null, "选择号码成功,号码为:" + number);
return number;
}
public static boolean isValidNumber(String number) {
if(!number.matches("\\d{14}")) {
return false;
}
for (int i = 0; i < number.length(); i += 2) {
String subNum = number.substring(i, i + 2);
int numValue = Integer.parseInt(subNum);
if (numValue < 1 || numValue > 36) {
return false;
}
}
return true;
}
个人的反思与总结:
收获:
通过这次彩票抽奖系统的课设,学习了图形化界面,各种弹窗的创建与实现,同时对ArrayList数组有了更加深刻的理解,对Java使用文本文件进行存储数据有了更具体客观的认识。在完成这次课设的过程中,读写写文件,背景更改出现路径等问题,在问ai和观看他人博客的过程中该问得到解决。
不足:
本次课设在多用户测试功能上没有完全完成,同时整体代码较冗余,还有空间再修正。