|
|
|
@ -0,0 +1,273 @@
|
|
|
|
|
package view;
|
|
|
|
|
|
|
|
|
|
import java.awt.Color;
|
|
|
|
|
import java.awt.Font;
|
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
|
|
|
|
import javax.swing.BorderFactory;
|
|
|
|
|
import javax.swing.JButton;
|
|
|
|
|
import javax.swing.JLabel;
|
|
|
|
|
import javax.swing.JOptionPane;
|
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
|
import javax.swing.JPasswordField;
|
|
|
|
|
import javax.swing.JTextField;
|
|
|
|
|
import javax.swing.SwingConstants;
|
|
|
|
|
import javax.swing.SwingUtilities;
|
|
|
|
|
|
|
|
|
|
import com.dao.impl.Accountimpl;
|
|
|
|
|
import com.javaBean.Account;
|
|
|
|
|
|
|
|
|
|
import javax.swing.JOptionPane;
|
|
|
|
|
import javax.swing.SwingUtilities;
|
|
|
|
|
import java.awt.Window;
|
|
|
|
|
/**
|
|
|
|
|
* LoginFrame 类是游戏登录界面的实现,继承自MyFrame,负责展示用户名和密码输入框以及登录、退出按钮。
|
|
|
|
|
*/
|
|
|
|
|
public class LoginFrame extends MyFrame {
|
|
|
|
|
private JTextField textAccountId; // 用户名文本框
|
|
|
|
|
private JPasswordField txtpasswordText; // 密码文本框
|
|
|
|
|
private JButton loginButton; // 登录按钮
|
|
|
|
|
private JButton cancelButton; // 退出按钮
|
|
|
|
|
private JLabel accountLabel; // 用户名标签
|
|
|
|
|
private JLabel passwordLabel; // 密码标签
|
|
|
|
|
/**
|
|
|
|
|
* 构造函数,初始化登录界面的标题、尺寸和组件。
|
|
|
|
|
* @param title 窗口标题
|
|
|
|
|
* @param width 窗口宽度
|
|
|
|
|
* @param height 窗口高度
|
|
|
|
|
*/
|
|
|
|
|
public LoginFrame(String title, int width, int height) {
|
|
|
|
|
super(title, width, height);
|
|
|
|
|
initComponents();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 初始化界面组件,设置布局和事件监听器。
|
|
|
|
|
*/
|
|
|
|
|
private void initComponents() {
|
|
|
|
|
JPanel contentPane = (JPanel) getContentPane();
|
|
|
|
|
contentPane.setLayout(null);
|
|
|
|
|
|
|
|
|
|
// 用户名标签和输入框
|
|
|
|
|
accountLabel = createLabel("用户名:", 51, 33);
|
|
|
|
|
contentPane.add(accountLabel);
|
|
|
|
|
textAccountId = createTextField(158, 33);
|
|
|
|
|
contentPane.add(textAccountId);
|
|
|
|
|
|
|
|
|
|
// 密码标签和输入框
|
|
|
|
|
passwordLabel = createLabel("密码:", 51, 83);
|
|
|
|
|
contentPane.add(passwordLabel);
|
|
|
|
|
txtpasswordText = createPasswordField(158, 83);
|
|
|
|
|
contentPane.add(txtpasswordText);
|
|
|
|
|
|
|
|
|
|
// 登录按钮
|
|
|
|
|
loginButton = createButton("登录", 70, 130);
|
|
|
|
|
loginButton.addActionListener(new ActionListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
attemptLogin();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
contentPane.add(loginButton);
|
|
|
|
|
// 创建退出按钮
|
|
|
|
|
// 使用createButton方法创建一个JButton组件,文本内容为"退出",放置在窗口中的位置为x=190, y=130,
|
|
|
|
|
// 并将生成的按钮对象赋值给cancelButton变量。
|
|
|
|
|
cancelButton = createButton("退出", 190, 130);
|
|
|
|
|
|
|
|
|
|
// 为cancelButton按钮添加事件监听器,当按钮被点击时,执行以下操作。
|
|
|
|
|
cancelButton.addActionListener(new ActionListener() {
|
|
|
|
|
@Override
|
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
|
// 显示一个确认对话框询问用户是否确定退出,对话框标题为"退出确认",消息为"确认退出吗?",
|
|
|
|
|
// 提供"Yes"和"No"两个按钮选项,用户的选择结果将通过showConfirmDialog方法返回。
|
|
|
|
|
int confirm = JOptionPane.showConfirmDialog(null, "确认退出吗?", "退出确认", JOptionPane.YES_NO_OPTION);
|
|
|
|
|
|
|
|
|
|
// 判断用户是否点击了"Yes"(即返回值为JOptionPane.YES_OPTION)
|
|
|
|
|
if (confirm == JOptionPane.YES_OPTION) {
|
|
|
|
|
// 再次显示一个对话框,内容为感谢信息"感谢您的游玩,期待您下次再来!",
|
|
|
|
|
// 对话框标题为"欢迎再次光临",类型为提示信息,包含一个"确定"按钮。
|
|
|
|
|
int option = JOptionPane.showOptionDialog(
|
|
|
|
|
// 参数1: 父组件,设为null表示对话框将没有明确的父窗口,它将被置于屏幕中央。
|
|
|
|
|
null,
|
|
|
|
|
//参数2: 要显示的消息,这里是感谢用户并期待他们再次光临的信息。
|
|
|
|
|
"感谢您的游玩,期待您下次再来!",
|
|
|
|
|
// 参数3: 对话框的标题,设置为"欢迎下次游玩"。
|
|
|
|
|
"欢迎下次游玩",
|
|
|
|
|
// 参数4: 选项类型,JOptionPane.OK_CANCEL_OPTION 表示对话框将显示“确定”和“取消”两个按钮。
|
|
|
|
|
JOptionPane.OK_CANCEL_OPTION,
|
|
|
|
|
// 参数5: 消息类型,JOptionPane.INFORMATION_MESSAGE 表示这是一个传递信息的对话框,
|
|
|
|
|
//通常会伴随有一个默认的信息图标,例如一个表示提示或注意的图标(比如一个蓝色的“i”信息图标)。
|
|
|
|
|
JOptionPane.INFORMATION_MESSAGE,
|
|
|
|
|
// 参数6: 自定义的图标,这里设为null,因此将使用上述消息类型默认的图标。
|
|
|
|
|
null,
|
|
|
|
|
// 参数7: 按钮的文字数组,定义了对话框底部按钮的文本。
|
|
|
|
|
// 这里只有一个按钮,文本为"确定"。
|
|
|
|
|
new Object[]{"确定" ,"取消"},
|
|
|
|
|
// 参数8: 默认选择的按钮的索引,在数组中从0开始计数。
|
|
|
|
|
// 这里设置为"确定"按钮,确保默认选中它。
|
|
|
|
|
"确定"// 设置默认选中的按钮为"确定"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 如果用户点击了"确定"按钮(即返回值为JOptionPane.OK_OPTION)
|
|
|
|
|
if (option == JOptionPane.OK_OPTION) {
|
|
|
|
|
// 获取触发事件的组件所属的窗口,并关闭该窗口。
|
|
|
|
|
Window window = SwingUtilities.getWindowAncestor((java.awt.Component)e.getSource());
|
|
|
|
|
if (window != null) {
|
|
|
|
|
window.dispose(); // 关闭窗口
|
|
|
|
|
}
|
|
|
|
|
// 注意:此处的System.exit(0)应该根据实际需求谨慎使用。
|
|
|
|
|
// 在用户点击"确定"关闭窗口后,直接退出整个应用程序。
|
|
|
|
|
// 通常,在关闭单个窗口时不应使用此方法,除非确实需要关闭整个应用。
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
if (option == JOptionPane.CANCEL_OPTION) {
|
|
|
|
|
// 获取触发事件的组件所属的窗口,并关闭该窗口。
|
|
|
|
|
Window window = SwingUtilities.getWindowAncestor((java.awt.Component)e.getSource());
|
|
|
|
|
if (window != null) {
|
|
|
|
|
window.dispose(); // 关闭窗口
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 将配置好的cancelButton按钮添加到窗体的主内容面板(contentPane)上,使之在UI界面上可见。
|
|
|
|
|
contentPane.add(cancelButton);
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 尝试登录操作,验证用户输入的用户名和密码。
|
|
|
|
|
*/
|
|
|
|
|
private void attemptLogin() {
|
|
|
|
|
// 获取用户输入的账号名
|
|
|
|
|
String name = textAccountId.getText();
|
|
|
|
|
// 获取用户输入的密码(字符数组形式以保护信息安全)
|
|
|
|
|
char[] password = txtpasswordText.getPassword();
|
|
|
|
|
// 将字符数组转换为String类型以便数据库查询
|
|
|
|
|
String pass = new String(password);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// 创建Accountimpl类的实例,用于执行用户验证逻辑
|
|
|
|
|
Accountimpl accountImpl = new Accountimpl();
|
|
|
|
|
// 调用validateUser方法验证用户名和密码是否匹配,返回对应的Account对象
|
|
|
|
|
Account account = accountImpl.validateUser(name, pass);
|
|
|
|
|
// 如果验证成功且账号ID不为空
|
|
|
|
|
if (account != null && !account.getuserid().isEmpty()) {
|
|
|
|
|
// 显示登录成功的消息框
|
|
|
|
|
JOptionPane.showMessageDialog(this, "登录成功!");
|
|
|
|
|
// 隐藏当前登录界面
|
|
|
|
|
setVisible(false);
|
|
|
|
|
// 启动游戏主界面
|
|
|
|
|
MyFrame gameFrame = new MyFrame("俄罗斯方块游戏界面");
|
|
|
|
|
gameFrame.setVisible(true);
|
|
|
|
|
} else {
|
|
|
|
|
// 如果验证失败,显示错误消息并提示重新输入
|
|
|
|
|
JOptionPane.showMessageDialog(this, "用户名或密码错误,请重新输入", "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
// 重置输入字段
|
|
|
|
|
resetFields();
|
|
|
|
|
}
|
|
|
|
|
} catch (SQLException ex) {
|
|
|
|
|
// 如果在登录过程中遇到数据库访问错误,显示错误消息并打印堆栈跟踪
|
|
|
|
|
JOptionPane.showMessageDialog(this, "登录失败,数据库访问错误: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 重置输入框内容。
|
|
|
|
|
*/
|
|
|
|
|
private void resetFields() {
|
|
|
|
|
textAccountId.setText("");
|
|
|
|
|
txtpasswordText.setText("");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建标签组件。
|
|
|
|
|
* @param text 标签文本
|
|
|
|
|
* @param x 横坐标
|
|
|
|
|
* @param y 纵坐标
|
|
|
|
|
* @return 创建好的标签对象
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
private JLabel createLabel(String text, int x, int y) {
|
|
|
|
|
//方法接收两个参数:text表示标签要显示的文本内容,x和y分别表示标签在容器中的横纵坐标位置。
|
|
|
|
|
JLabel label = new JLabel(text);
|
|
|
|
|
//利用传入的text参数创建一个新的JLabel对象。
|
|
|
|
|
label.setHorizontalAlignment(SwingConstants.RIGHT);
|
|
|
|
|
//设置标签中文本的水平对齐方式为右对齐。这意味着文本将会在标签内靠右显示。
|
|
|
|
|
label.setBounds(x, y, 83, 30);
|
|
|
|
|
//使用setBounds方法设定标签的精确位置和尺寸。这里的参数分别是标签左上角的横纵坐标(x, y),以及标签的宽度83和高度30。
|
|
|
|
|
label.setForeground(Color.BLACK);
|
|
|
|
|
//设定标签文本的颜色为黑色。
|
|
|
|
|
label.setFont(new Font("微软雅黑", Font.PLAIN, 15));
|
|
|
|
|
//设置标签文本的字体为微软雅黑,样式为普通(PLAIN),字号为15点。
|
|
|
|
|
return label;
|
|
|
|
|
}
|
|
|
|
|
//透明背景(setOpaque(false))和无边框(setBorder(null))
|
|
|
|
|
/**
|
|
|
|
|
* 创建用户名文本框组件。
|
|
|
|
|
* @param x 横坐标
|
|
|
|
|
* @param y 纵坐标
|
|
|
|
|
* @return 创建好的文本框对象
|
|
|
|
|
*/
|
|
|
|
|
private JTextField createTextField(int x, int y) {
|
|
|
|
|
JTextField textField = new JTextField(10);
|
|
|
|
|
textField.setBounds(x, y, 157, 30);
|
|
|
|
|
textField.setFont(new Font("微软雅黑", Font.PLAIN, 15));
|
|
|
|
|
textField.setBorder(BorderFactory.createLineBorder(Color.PINK, 4)); // 参数分别为颜色和边框宽度
|
|
|
|
|
/*textField.setOpaque(false);
|
|
|
|
|
textField.setBorder(null);*/
|
|
|
|
|
// 移除了透明背景和无边框的设置,以确保文本框可见
|
|
|
|
|
return textField;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建密码框组件。
|
|
|
|
|
* @param x 横坐标
|
|
|
|
|
* @param y 纵坐标
|
|
|
|
|
* @return 创建好的密码框对象
|
|
|
|
|
*/
|
|
|
|
|
private JPasswordField createPasswordField(int x, int y) {
|
|
|
|
|
JPasswordField passwordField = new JPasswordField(10);
|
|
|
|
|
passwordField.setBounds(x, y, 157, 30);
|
|
|
|
|
passwordField.setFont(new Font("微软雅黑", Font.PLAIN, 15));
|
|
|
|
|
passwordField.setBorder(BorderFactory.createLineBorder(Color.PINK, 4)); // 参数分别为颜色和边框宽度
|
|
|
|
|
/*passwordField.setOpaque(false);
|
|
|
|
|
passwordField.setBorder(null);*/
|
|
|
|
|
// 移除了透明背景和无边框的设置
|
|
|
|
|
return passwordField;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 创建按钮组件。
|
|
|
|
|
* @param text 按钮文本
|
|
|
|
|
* @param x 横坐标
|
|
|
|
|
* @param y 纵坐标
|
|
|
|
|
* @return 创建好的按钮对象
|
|
|
|
|
*/
|
|
|
|
|
private JButton createButton(String text, int x, int y) {
|
|
|
|
|
JButton button = new JButton(text);
|
|
|
|
|
button.setFont(new Font("微软雅黑", Font.PLAIN, 17));
|
|
|
|
|
button.setBounds(x, y, 100, 40);
|
|
|
|
|
button.setForeground(Color.BLACK);
|
|
|
|
|
button.setOpaque(true);
|
|
|
|
|
button.setContentAreaFilled(true);
|
|
|
|
|
button.setBackground(Color.PINK);
|
|
|
|
|
button.setBorder(BorderFactory.createLineBorder(Color.PINK, 2)); // 参数分别为颜色和边框宽度
|
|
|
|
|
return button;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**4
|
|
|
|
|
* 应用程序入口点。
|
|
|
|
|
* @param args 命令行参数
|
|
|
|
|
*/
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
SwingUtilities.invokeLater(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
new LoginFrame("俄罗斯方块登录窗口", 400, 255).setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|