demo/Main.java

682 lines
26 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class LotteryProgram extends JFrame {
// Define tech-style colors
private static final Color COLOR_BG = new Color(30, 33, 40); // Dark gray background
private static final Color COLOR_PANEL = new Color(43, 47, 57); // Panel background
private static final Color COLOR_ACCENT = new Color(0, 180, 216); // Tech blue accent
private static final Color COLOR_TEXT = new Color(220, 223, 228); // Bright white text
private static final Color COLOR_TABLE_BG = new Color(43, 47, 57);
private static final Color COLOR_TABLE_SEL = new Color(0, 120, 215);
private static final Color COLOR_TABLE_GRID = new Color(60, 64, 72);
// Data storage
private List<String> allParticipants = new ArrayList<>();
private List<String> remainingParticipants = new ArrayList<>();
private List<Prize> prizes = new ArrayList<>();
// UI components
private JTextArea nameInputArea;
private JTable prizeTable;
private DefaultTableModel prizeTableModel;
private JComboBox<Prize> prizeComboBox;
private JLabel lblRemainingCount;
private JLabel lblRollingName;
private JTextArea resultArea;
private JSpinner spinnerDrawCount;
// Data file path (Cross-platform compatible)
private static final String DATA_FILE = System.getProperty("user.home") + File.separator + ".lottery_data.dat";
// Cross-platform font support
private static Font getCompatibleFont(int style, int size) {
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
return new Font("PingFang SC", style, size);
} else if (System.getProperty("os.name").toLowerCase().contains("win")) {
return new Font("Microsoft YaHei", style, size);
} else {
return new Font("SansSerif", style, size);
}
}
public LotteryProgram() {
// Setup macOS specific properties if applicable
setupMacOSProperties();
setTitle("xxxxxxx公司年终大抽奖系统");
setSize(1200, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new BorderLayout(10, 10));
getContentPane().setBackground(COLOR_BG);
// Initialize data
loadData();
if (prizes.isEmpty()) {
prizes.add(new Prize("特等奖", 1));
prizes.add(new Prize("一等奖", 3));
prizes.add(new Prize("二等奖", 10));
prizes.add(new Prize("三等奖", 20));
}
// Initialize UI
initComponents();
// Update UI state
updatePrizeTable();
updatePrizeComboBox();
updateRemainingCount();
}
private void setupMacOSProperties() {
if (System.getProperty("os.name").toLowerCase().contains("mac")) {
System.setProperty("apple.laf.useScreenMenuBar", "true");
System.setProperty("com.apple.mrj.application.apple.menu.about.name", "Lottery Program");
}
}
private void initComponents() {
// === Top: Rolling display area ===
JPanel topPanel = createPanel(new BorderLayout());
topPanel.setBorder(new EmptyBorder(20, 20, 20, 20));
lblRollingName = new JLabel("准备就绪", SwingConstants.CENTER);
lblRollingName.setFont(getCompatibleFont(Font.BOLD, 60));
lblRollingName.setForeground(COLOR_ACCENT);
lblRollingName.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 0));
topPanel.add(lblRollingName, BorderLayout.CENTER);
add(topPanel, BorderLayout.NORTH);
// === Middle: Left and right split ===
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setDividerLocation(450);
splitPane.setBackground(COLOR_BG);
splitPane.setDividerSize(5);
// --- Left: Settings area ---
JPanel leftPanel = createPanel(new BorderLayout());
leftPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
// 1. Name management
JPanel namePanel = new JPanel(new BorderLayout());
namePanel.setBackground(COLOR_PANEL);
namePanel.setBorder(createTitledBorder("名单管理 (批量添加,一行一个)"));
nameInputArea = new JTextArea();
nameInputArea.setBackground(new Color(30, 33, 40));
nameInputArea.setForeground(COLOR_TEXT);
nameInputArea.setFont(getCompatibleFont(Font.PLAIN, 14));
nameInputArea.setCaretColor(COLOR_TEXT);
JScrollPane nameScroll = new JScrollPane(nameInputArea);
nameScroll.setBorder(new LineBorder(COLOR_TABLE_GRID));
namePanel.add(nameScroll, BorderLayout.CENTER);
JButton btnUpdateNames = createTechButton("更新/重置名单");
btnUpdateNames.addActionListener(e -> updateNames());
JPanel nameBtnPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
nameBtnPanel.setBackground(COLOR_PANEL);
nameBtnPanel.add(btnUpdateNames);
namePanel.add(nameBtnPanel, BorderLayout.SOUTH);
leftPanel.add(namePanel, BorderLayout.CENTER);
// 2. Prize management
JPanel prizeManagePanel = new JPanel(new BorderLayout());
prizeManagePanel.setBackground(COLOR_PANEL);
prizeManagePanel.setBorder(createTitledBorder("奖项设置 (右键点击可修改)"));
prizeTableModel = new DefaultTableModel(new Object[]{"奖项名称", "总人数", "剩余"}, 0) {
@Override
public boolean isCellEditable(int row, int column) { return false; }
@Override
public Class<?> getColumnClass(int columnIndex) {
return columnIndex == 0 ? String.class : Integer.class;
}
};
prizeTable = new JTable(prizeTableModel);
styleTable(prizeTable);
// Table right-click menu
prizeTable.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
int row = prizeTable.rowAtPoint(e.getPoint());
if (row >= 0) {
prizeTable.setRowSelectionInterval(row, row);
showTablePopupMenu(e.getComponent(), e.getX(), e.getY(), row);
}
}
}
});
prizeManagePanel.add(new JScrollPane(prizeTable), BorderLayout.CENTER);
JPanel prizeBtnPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
prizeBtnPanel.setBackground(COLOR_PANEL);
JButton btnAddPrize = createTechButton("添加奖项");
btnAddPrize.addActionListener(e -> addPrize());
JButton btnDelPrize = createTechButton("删除选中");
btnDelPrize.addActionListener(e -> deletePrize());
JButton btnResetPrizes = createTechButton("重置奖项数量");
btnResetPrizes.addActionListener(e -> resetPrizes());
prizeBtnPanel.add(btnAddPrize);
prizeBtnPanel.add(btnDelPrize);
prizeBtnPanel.add(btnResetPrizes);
prizeManagePanel.add(prizeBtnPanel, BorderLayout.SOUTH);
leftPanel.add(prizeManagePanel, BorderLayout.SOUTH);
// --- Right: Control and results ---
JPanel rightPanel = createPanel(new BorderLayout());
rightPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
// Control area
JPanel controlPanel = createPanel(new GridBagLayout());
controlPanel.setBorder(createTitledBorder("抽奖控制"));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
// Style labels
Font labelFont = getCompatibleFont(Font.PLAIN, 16);
gbc.gridx = 0; gbc.gridy = 0;
JLabel lblSelect = new JLabel("选择奖项:");
lblSelect.setForeground(COLOR_TEXT);
lblSelect.setFont(labelFont);
controlPanel.add(lblSelect, gbc);
gbc.gridx = 1; gbc.weightx = 1.0;
styleComboBox(prizeComboBox = new JComboBox<>());
controlPanel.add(prizeComboBox, gbc);
gbc.gridx = 0; gbc.gridy = 1; gbc.weightx = 0;
JLabel lblPool = new JLabel("奖池剩余:");
lblPool.setForeground(COLOR_TEXT);
lblPool.setFont(labelFont);
controlPanel.add(lblPool, gbc);
gbc.gridx = 1; gbc.weightx = 1.0;
lblRemainingCount = new JLabel("0 人");
lblRemainingCount.setForeground(COLOR_ACCENT);
lblRemainingCount.setFont(getCompatibleFont(Font.BOLD, 16));
controlPanel.add(lblRemainingCount, gbc);
gbc.gridx = 0; gbc.gridy = 2; gbc.weightx = 0;
JLabel lblDraw = new JLabel("本次抽取人数:");
lblDraw.setForeground(COLOR_TEXT);
lblDraw.setFont(labelFont);
controlPanel.add(lblDraw, gbc);
gbc.gridx = 1; gbc.weightx = 1.0;
spinnerDrawCount = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1));
styleSpinner(spinnerDrawCount);
controlPanel.add(spinnerDrawCount, gbc);
// Round button
gbc.gridx = 0; gbc.gridy = 3; gbc.gridwidth = 2;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
RoundButton btnStart = new RoundButton("开始 / 停止");
btnStart.setBackground(new Color(220, 53, 69)); // Bright red
btnStart.setForeground(Color.WHITE);
btnStart.setFont(getCompatibleFont(Font.BOLD, 18));
btnStart.setPreferredSize(new Dimension(150, 150));
btnStart.addActionListener(e -> toggleLottery());
controlPanel.add(btnStart, gbc);
rightPanel.add(controlPanel, BorderLayout.NORTH);
// Results area
JPanel resultPanel = new JPanel(new BorderLayout());
resultPanel.setBackground(COLOR_PANEL);
resultPanel.setBorder(createTitledBorder("中奖名单"));
resultArea = new JTextArea();
resultArea.setEditable(false);
resultArea.setBackground(new Color(30, 33, 40));
resultArea.setForeground(COLOR_TEXT);
// Monospaced font for results looks better on all platforms
resultArea.setFont(new Font("Monospaced", Font.PLAIN, 14));
resultPanel.add(new JScrollPane(resultArea), BorderLayout.CENTER);
JButton btnClearResult = createTechButton("清空结果");
btnClearResult.addActionListener(e -> resultArea.setText(""));
JPanel resBtnPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
resBtnPanel.setBackground(COLOR_PANEL);
resBtnPanel.add(btnClearResult);
resultPanel.add(resBtnPanel, BorderLayout.SOUTH);
rightPanel.add(resultPanel, BorderLayout.CENTER);
splitPane.setLeftComponent(leftPanel);
splitPane.setRightComponent(rightPanel);
add(splitPane, BorderLayout.CENTER);
}
// === UI helper methods: Tech-style ===
private JPanel createPanel(LayoutManager layout) {
JPanel p = new JPanel(layout);
p.setBackground(COLOR_PANEL);
p.setBorder(new EmptyBorder(5, 5, 5, 5));
return p;
}
private TitledBorder createTitledBorder(String title) {
TitledBorder border = BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(COLOR_ACCENT, 1),
title,
TitledBorder.LEFT,
TitledBorder.TOP,
getCompatibleFont(Font.BOLD, 14),
COLOR_ACCENT);
border.setTitleColor(COLOR_ACCENT);
return border;
}
private JButton createTechButton(String text) {
JButton btn = new JButton(text);
btn.setBackground(new Color(0, 123, 255));
btn.setForeground(Color.WHITE);
btn.setFocusPainted(false);
btn.setFont(getCompatibleFont(Font.PLAIN, 14));
btn.setBorder(new EmptyBorder(8, 15, 8, 15));
btn.setCursor(new Cursor(Cursor.HAND_CURSOR));
btn.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) { btn.setBackground(btn.getBackground().brighter()); }
@Override
public void mouseExited(MouseEvent e) { btn.setBackground(new Color(0, 123, 255)); }
});
return btn;
}
private void styleTable(JTable table) {
table.setBackground(COLOR_TABLE_BG);
table.setForeground(COLOR_TEXT);
table.setGridColor(COLOR_TABLE_GRID);
table.setRowHeight(30);
table.setSelectionBackground(COLOR_TABLE_SEL);
table.setSelectionForeground(Color.WHITE);
table.setFont(getCompatibleFont(Font.PLAIN, 14));
table.getTableHeader().setBackground(new Color(52, 58, 64));
table.getTableHeader().setForeground(COLOR_TEXT);
table.getTableHeader().setFont(getCompatibleFont(Font.BOLD, 14));
// Custom cell renderer to maintain background color
DefaultTableCellRenderer renderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (!isSelected) {
c.setBackground(COLOR_TABLE_BG);
}
return c;
}
};
table.setDefaultRenderer(Object.class, renderer);
}
private void styleComboBox(JComboBox<?> combo) {
combo.setBackground(new Color(52, 58, 64));
combo.setForeground(COLOR_TEXT);
combo.setFont(getCompatibleFont(Font.PLAIN, 14));
}
private void styleSpinner(JSpinner spinner) {
JComponent editor = spinner.getEditor();
if (editor instanceof JSpinner.DefaultEditor) {
((JSpinner.DefaultEditor) editor).getTextField().setBackground(new Color(52, 58, 64));
((JSpinner.DefaultEditor) editor).getTextField().setForeground(COLOR_TEXT);
((JSpinner.DefaultEditor) editor).getTextField().setFont(getCompatibleFont(Font.PLAIN, 14));
}
}
// === Logic processing methods ===
private void showTablePopupMenu(Component invoker, int x, int y, int row) {
JPopupMenu popup = new JPopupMenu();
popup.setBackground(COLOR_PANEL);
popup.setForeground(COLOR_TEXT);
JMenuItem editTotalItem = new JMenuItem("修改总人数");
JMenuItem editRemainItem = new JMenuItem("修改剩余人数");
// Unified style
for(JMenuItem item : new JMenuItem[]{editTotalItem, editRemainItem}) {
item.setBackground(COLOR_PANEL);
item.setForeground(COLOR_TEXT);
}
editTotalItem.addActionListener(e -> {
Prize p = prizes.get(row);
String newVal = JOptionPane.showInputDialog(this, "修改 [" + p.getName() + "] 的总人数:", p.getTotalCount());
processEdit(p, newVal, true);
});
editRemainItem.addActionListener(e -> {
Prize p = prizes.get(row);
String newVal = JOptionPane.showInputDialog(this, "修改 [" + p.getName() + "] 的剩余人数:", p.getRemaining());
processEdit(p, newVal, false);
});
popup.add(editTotalItem);
popup.add(editRemainItem);
popup.show(invoker, x, y);
}
private void processEdit(Prize p, String newVal, boolean isTotal) {
try {
if (newVal != null) {
int count = Integer.parseInt(newVal);
if (count < 0) throw new NumberFormatException();
if (isTotal) {
if (count < (p.getTotalCount() - p.getRemaining())) {
JOptionPane.showMessageDialog(this, "新人数不能少于已中奖人数 (" + (p.getTotalCount() - p.getRemaining()) + ")");
return;
}
// Keep awarded count unchanged
int awarded = p.getTotalCount() - p.getRemaining();
p.setTotalCount(count);
p.setRemaining(count - awarded);
} else {
if (count > p.getTotalCount()) {
JOptionPane.showMessageDialog(this, "剩余人数不能大于总人数!");
return;
}
p.setRemaining(count);
}
updatePrizeTable();
updatePrizeComboBox();
saveData();
}
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(this, "请输入有效的数字!");
}
}
private void updateNames() {
String text = nameInputArea.getText();
String[] lines = text.split("\n");
allParticipants.clear();
for (String line : lines) {
String name = line.trim();
if (!name.isEmpty()) {
allParticipants.add(name);
}
}
remainingParticipants.clear();
remainingParticipants.addAll(allParticipants);
updateRemainingCount();
JOptionPane.showMessageDialog(this, "名单已更新!共 " + allParticipants.size() + " 人。");
saveData();
}
private void addPrize() {
String name = JOptionPane.showInputDialog(this, "请输入奖项名称:");
if (name == null || name.trim().isEmpty()) return;
String countStr = JOptionPane.showInputDialog(this, "请输入中奖人数:");
try {
int count = Integer.parseInt(countStr);
if (count <= 0) throw new NumberFormatException();
prizes.add(new Prize(name, count));
updatePrizeTable();
updatePrizeComboBox();
saveData();
} catch (NumberFormatException e) {
JOptionPane.showMessageDialog(this, "请输入有效的正整数人数!");
}
}
private void deletePrize() {
int row = prizeTable.getSelectedRow();
if (row >= 0) {
prizes.remove(row);
updatePrizeTable();
updatePrizeComboBox();
saveData();
} else {
JOptionPane.showMessageDialog(this, "请先选择要删除的奖项!");
}
}
private void resetPrizes() {
int confirm = JOptionPane.showConfirmDialog(this, "确定要重置所有奖项的剩余人数吗?", "确认", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
for (Prize p : prizes) p.resetRemaining();
updatePrizeTable();
saveData();
}
}
private void updatePrizeTable() {
prizeTableModel.setRowCount(0);
for (Prize p : prizes) {
prizeTableModel.addRow(new Object[]{p.getName(), p.getTotalCount(), p.getRemaining()});
}
}
private void updatePrizeComboBox() {
Object selected = prizeComboBox.getSelectedItem();
prizeComboBox.removeAllItems();
for (Prize p : prizes) prizeComboBox.addItem(p);
if (selected != null) prizeComboBox.setSelectedItem(selected);
}
private void updateRemainingCount() {
lblRemainingCount.setText(remainingParticipants.size() + "");
}
private Timer timer;
private boolean isRunning = false;
private void toggleLottery() {
Prize selectedPrize = (Prize) prizeComboBox.getSelectedItem();
if (selectedPrize == null) {
JOptionPane.showMessageDialog(this, "请先添加并选择一个奖项!");
return;
}
if (selectedPrize.getRemaining() <= 0) {
JOptionPane.showMessageDialog(this, "该奖项已抽完!如需重新抽取,请重置奖项。");
return;
}
if (remainingParticipants.isEmpty()) {
JOptionPane.showMessageDialog(this, "奖池已空,请添加更多名单!");
return;
}
if (isRunning) stopLottery(selectedPrize);
else startLottery();
}
private void startLottery() {
isRunning = true;
timer = new Timer(30, e -> { // Speed up rolling
if (!remainingParticipants.isEmpty()) {
int randomIndex = (int) (Math.random() * remainingParticipants.size());
lblRollingName.setText(remainingParticipants.get(randomIndex));
}
});
timer.start();
}
private void stopLottery(Prize prize) {
isRunning = false;
timer.stop();
int drawCount = (int) spinnerDrawCount.getValue();
if (drawCount > prize.getRemaining()) {
drawCount = prize.getRemaining();
JOptionPane.showMessageDialog(this, "剩余名额不足,将抽取剩余的 " + drawCount + " 人。");
}
if (drawCount > remainingParticipants.size()) {
drawCount = remainingParticipants.size();
JOptionPane.showMessageDialog(this, "奖池总人数不足,将抽取剩余的 " + drawCount + " 人。");
}
List<String> currentWinners = new ArrayList<>();
for (int i = 0; i < drawCount; i++) {
Collections.shuffle(remainingParticipants);
String winner = remainingParticipants.remove(0);
currentWinners.add(winner);
prize.decrementRemaining();
}
if (currentWinners.size() == 1) {
lblRollingName.setText(currentWinners.get(0));
} else {
lblRollingName.setText("恭喜 " + currentWinners.size() + " 位中奖者!");
}
updatePrizeTable();
updateRemainingCount();
String time = java.time.LocalDateTime.now().toString().substring(0, 19);
String winnersStr = String.join(", ", currentWinners);
resultArea.append(String.format("[%s] %s: %s\n", time, prize.getName(), winnersStr));
saveData();
}
private void saveData() {
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream(DATA_FILE))) {
oos.writeObject(allParticipants);
oos.writeObject(prizes);
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "数据保存失败: " + e.getMessage());
}
}
@SuppressWarnings("unchecked")
private void loadData() {
File file = new File(DATA_FILE);
if (file.exists()) {
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream(DATA_FILE))) {
allParticipants = (List<String>) ois.readObject();
prizes = (List<Prize>) ois.readObject();
remainingParticipants = new ArrayList<>(allParticipants);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "数据加载失败,将使用默认设置。");
// Reset to defaults if load fails
allParticipants.clear();
remainingParticipants.clear();
prizes.clear();
}
}
}
static class Prize implements Serializable {
private String name;
private int totalCount;
private int remainingCount;
public Prize(String name, int totalCount) {
this.name = name;
this.totalCount = totalCount;
this.remainingCount = totalCount;
}
public String getName() { return name; }
public int getTotalCount() { return totalCount; }
public int getRemaining() { return remainingCount; }
public void setTotalCount(int totalCount) { this.totalCount = totalCount; }
public void setRemaining(int remainingCount) { this.remainingCount = remainingCount; }
public void decrementRemaining() { if (remainingCount > 0) remainingCount--; }
public void resetRemaining() { remainingCount = totalCount; }
@Override
public String toString() { return name + " (剩: " + remainingCount + ")"; }
}
class RoundButton extends JButton {
public RoundButton(String label) {
super(label);
setContentAreaFilled(false);
setFocusPainted(false);
setBorderPainted(false);
setCursor(new Cursor(Cursor.HAND_CURSOR));
}
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (getModel().isArmed()) {
g2.setColor(getBackground().darker());
} else {
g2.setColor(getBackground());
}
g2.fillOval(0, 0, getSize().width - 1, getSize().height - 1);
super.paintComponent(g);
}
@Override
protected void paintBorder(Graphics g) { }
@Override
public boolean contains(int x, int y) {
if (shape == null || !shape.getBounds().equals(getBounds())) {
shape = new java.awt.geom.Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
private transient java.awt.Shape shape;
}
public static void main(String[] args) {
try {
// Force UTF-8 property early (best effort)
System.setProperty("file.encoding", "UTF-8");
// Set CrossPlatform LookAndFeel for consistency
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
// Optional: Set global font defaults for the LookAndFeel
Font defaultFont = getCompatibleFont(Font.PLAIN, 12);
UIManager.put("Button.font", defaultFont);
UIManager.put("Label.font", defaultFont);
UIManager.put("Table.font", defaultFont);
UIManager.put("TableHeader.font", defaultFont);
UIManager.put("TextField.font", defaultFont);
UIManager.put("TextArea.font", defaultFont);
UIManager.put("ComboBox.font", defaultFont);
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> {
LotteryProgram frame = new LotteryProgram();
frame.setVisible(true);
});
}
}