JAVA项目之天天酷跑-Day01
项目借鉴: https://blog.csdn.net/qq_45909299
登陆界面制作
分析要求
首先要有用户名和密码的输入以及判断是否可以正确登录
- 用户名或密码为空则不能登录
- 用户名与密码不匹配不能登录
- 用户名和密码匹配才能登陆
登录按钮以及取消按钮(增加时间监听)
添加背景图片以及logo
创建LoginFrame类
LoginFrame类继承JFrame类
public class LoginFrame extends JFrame {
JLabel userLabel;//用户名变量(文本)
JTextField userField;//用户名输入框(文本输入框)
JLabel userLabel2;//密码变量(文本)
JPasswordField userFiled2;//密码输入框(文本输入框)
JButton Login, Cancel;
}
LoginFrame类的构造函数
public LoginFrame() {
}
给用户名以及密码标签设置属性
userLabel = new JLabel("用户名");
userLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
userLabel2 = new JLabel("密 码");
userLabel2.setFont(new Font("微软雅黑", Font.BOLD, 18));
设置Label布局并添加到Frame中
userLabel.setBounds(20, 220, 100, 30);
this.add(userLabel);
userLabel2.setBounds(20, 280, 100, 30);
this.add(userLabel2);
完善用户名输入框和密码输入框
//用户名输入框
userField = new JTextField();
userField.setBounds(80, 220, 100, 30);
//设置输入框凹陷效果
userField.setBorder(BorderFactory.createLoweredBevelBorder());
//设置输入框背景透明
userField.setOpaque(false);
this.add(userField);
userFiled2 = new JPasswordField();
userFiled2.setBounds(80, 280, 100, 30);
userFiled2.setBorder(BorderFactory.createLoweredBevelBorder());
userFiled2.setOpaque(false);
this.add(userFiled2);
设计登录按钮
Login = new JButton("登录");
Login.setBounds(45, 350, 60, 36);
为登录按钮绑定事件监听
Login.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框内容
String userName = userField.getText();
String password = new String(userFiled2.getPassword());
if("THEO".equals(userName) && "123".equals(password)) {
//登陆成功
JOptionPane.showMessageDialog(null, "欢迎" + userName + "来到天天酷跑");
//跳转到下一个界面
//关闭当前界面
dispose();
} else if("".equals(userName) || "".equals(password)) {
JOptionPane.showMessageDialog(null, "用户名 / 密码不能为空,请重新输入");
} else {
JOptionPane.showMessageDialog(null, "用户名 / 密码错误");
}
}
});
this.add(Login);
这里的登陆判定原作者做的比较简单,本人打算后续完善。
完善取消按钮
//取消按钮
Cancel = new JButton("取消");
Cancel.setBounds(135, 350, 60, 36);
this.add(Cancel);
//绑定取消按钮的事件监听
Cancel.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
创建面板
LoginPanel panel = new LoginPanel();
this.add(panel);
此处的LoginPanel是JPanel的子类
设置Frame的基本属性
this.setSize(900, 530);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setUndecorated(false);
this.setTitle("天天酷跑-THEO制作");
设置Frame的logo
this.setIconImage(new ImageIcon("/resources/images/115.png").getImage());
this.setVisible(true);
LoginPanel类的实现
static class LoginPanel extends JPanel {//面板
//背景图片变量
Image background;
public LoginPanel() {
}
//重写paint方法
@Override
public void paint(Graphics g) {
}
}
设置背景图片
public LoginPanel() {
try {
background = ImageIO.read(new File("resources/images/login.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
ImageIO.read()
有异常需要捕获
重写paint方法
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制背景图片
g.drawImage(background, 0, 0, 900, 530, null);//900, 530为宽高
}
至此我们的登录界面已经大致完善
整体代码如下
package cn.sqc.runday.view;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
/**
* @author THEO
* date 2021-3-23
* 登录界面
*/
public class LoginFrame extends JFrame {
JLabel userLabel;//用户名变量(文本)
JTextField userField;//用户名输入框(文本输入框)
JLabel userLabel2;//密码变量(文本)
JPasswordField userFiled2;//密码输入框(文本输入框)
JButton Login, Cancel;
public LoginFrame() {
userLabel = new JLabel("用户名");
userLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
userLabel2 = new JLabel("密 码");
userLabel2.setFont(new Font("微软雅黑", Font.BOLD, 18));
//绝对布局
userLabel.setBounds(20, 220, 100, 30);
this.add(userLabel);
userLabel2.setBounds(20, 280, 100, 30);
this.add(userLabel2);
//用户名输入框
userField = new JTextField();
userField.setBounds(80, 220, 100, 30);
//设置输入框凹陷效果
userField.setBorder(BorderFactory.createLoweredBevelBorder());
//设置输入框背景透明
userField.setOpaque(false);
this.add(userField);
userFiled2 = new JPasswordField();
userFiled2.setBounds(80, 280, 100, 30);
userFiled2.setBorder(BorderFactory.createLoweredBevelBorder());
userFiled2.setOpaque(false);
this.add(userFiled2);
//登录按钮
Login = new JButton("登录");
Login.setBounds(45, 350, 60, 36);
// Login.setBackground(new Color(44, 22, 44));//背景色
// Login.setForeground(Color.BLUE);//前景色
//绑定登录按钮的事件监听
Login.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
//获取输入框内容
String userName = userField.getText();
String password = new String(userFiled2.getPassword());
if("THEO".equals(userName) && "123".equals(password)) {
//登陆成功
JOptionPane.showMessageDialog(null, "欢迎" + userName + "来到天天酷跑");
//跳转到下一个界面
//关闭当前界面
dispose();
} else if("".equals(userName) || "".equals(password)) {
JOptionPane.showMessageDialog(null, "用户名 / 密码不能为空,请重新输入");
} else {
JOptionPane.showMessageDialog(null, "用户名 / 密码错误");
}
}
});
this.add(Login);
//取消按钮
Cancel = new JButton("取消");
Cancel.setBounds(135, 350, 60, 36);
this.add(Cancel);
//绑定取消按钮的事件监听
Cancel.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
//创建背景面板,并添加到窗体上去
LoginPanel panel = new LoginPanel();
this.add(panel);
//设置登录界面的基本属性
this.setSize(900, 530);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setUndecorated(false);
this.setTitle("天天酷跑-THEO制作");
//设置窗体的Logo图标
this.setIconImage(new ImageIcon("/resources/images/115.png").getImage());
this.setVisible(true);
}
public static void main(String[] args) {
new LoginFrame();
}
static class LoginPanel extends JPanel {//面板
//背景图片变量
Image background;
public LoginPanel() {
try {
background = ImageIO.read(new File("resources/images/login.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
//重写paint方法
@Override
public void paint(Graphics g) {
super.paint(g);
//绘制背景图片
g.drawImage(background, 0, 0, 900, 530, null);//900, 530为宽高
}
}
}
问题
在写完所有代码后,如果使用 IDEA run一下,就会发现
欸?咋有异常
javax.imageio.IIOException: Can't read input file!
at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
at cn.sqc.runday.view.LoginFrame$LoginPanel.<init>(LoginFrame.java:116)
at cn.sqc.runday.view.LoginFrame.<init>(LoginFrame.java:90)
at cn.sqc.runday.view.LoginFrame.main(LoginFrame.java:107)
界面虽然可以正常展示但是
emm…怎么肥事
赶紧看看报错并定位错误位置
background = ImageIO.read(new File("resources/images/login.jpg"));
发现问题出在这一句
报错信息是 can’t read input ,这就很让人迷惑,什么叫不能读取输入,于是上网搜索原因,在尝试过无数方法看了很多篇stackoverflow的提问后,还是一头雾水,勉强理解了一点,好像是在加载类的时候会出现问题,具体原因还没有搞清楚,希望有大佬解惑,大多数回答建议使用getClass().getResource("xxx")
于是我把代码改成了如下
background = ImageIO.read(getClass().getResource(("resources/images/login.jpg")));
但是问题仍然没有解决
java.lang.IllegalArgumentException: input == null!
懵逼了,这咋整,这回连界面都没出来
于是忽然想到了类加载器classLoader
,于是代码就改成了下面的样子
background = ImageIO.read(getClass().getClassLoader().getResource(("resources/images/login.jpg")));
这回终于是成功了
但是我还是对代码进行了更改
String path = getClass().getClassLoader().getResource("resources/images/login.jpg").getPath();
background = ImageIO.read(new File(path));
以及上面的logo代码
String path = getClass().getClassLoader().getResource("resources/images/115.png").getPath();
this.setIconImage(new ImageIcon(path).getImage());
完美解决问题
对功能进行检验
密码用户名为空
密码用户名错误
所需功能大致完成,bingo