java后端开发day24--阶段项目(一)
(以下内容全部来自上述课程)
GUI:Graphical User Interface 图形用户接口,采取图形化的方式显示操作界面
分为两套体系:AWT包(有兼容问题)和Swing包(常用)
拼图小游戏目的:
- 锻炼逻辑思维能力
- 知道前面学习的知识点在实际开发场景中的应用场景
1.主界面分析
1.创建主界面1
- 到idea中创建一个宽603像素,高680像素的游戏主界面
- 到idea中创建一个宽488像素,高430像素的登录界面
- 到idea中创建一个宽488像素,高500像素的注册界面
1.LoginJFrame
package com.woziji.ui;
import javax.swing.*;
public class LoginJFrame extends javax.swing.JFrame{
//登录界面
//以后和登录相关的所有逻辑都写在这个类中
public LoginJFrame(){
//在创建登陆界面的时候,同时给这个界面去设置一些信息
//比如:宽高,直接展示出来
this.setSize(488,430);
this.setVisible(true);
}
}
2.RegisterJFrame
package com.woziji.ui;
public class RegisterJFrame extends javax.swing.JFrame{
//注册界面
//以后和注册相关的所有逻辑都写在这个类中
public RegisterJFrame(){
this.setSize(488,500);
this.setVisible(true);
}
}
3.GameJFrame
package com.woziji.ui;
public class GameJFrame extends javax.swing.JFrame {
//JFrame 界面,窗体
//子类呢? 也表示界面,窗体
//规定:GameJFrame 表示游戏的主界面
//以后和游戏相关的所有逻辑都写在这个类中
public GameJFrame() {
this.setSize(603,680);
this.setVisible(true);
}
}
4.App
import com.woziji.ui.GameJFrame;
import com.woziji.ui.LoginJFrame;
import com.woziji.ui.RegisterJFrame;
public class App {
public static void main(String[] args) {
//表示程序的入口
//如果我们想开启一个界面,就创建谁的对象
new LoginJFrame();
new GameJFrame();
new RegisterJFrame();
}
}
2.创建主界面2
用继承改写上述主界面,并思考用继承改写的好处
1.LoginJFrame
package com.woziji.ui;
import javax.swing.*;
public class LoginJFrame extends javax.swing.JFrame{
//登录界面
//以后和登录相关的所有逻辑都写在这个类中
public LoginJFrame(){
//在创建登陆界面的时候,同时给这个界面去设置一些信息
//比如:宽高,直接展示出来
this.setSize(488,430);
this.setVisible(true);
//设置界面的标题
this.setTitle("拼图 登录");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
}
}
2.RegisterJFrame
package com.woziji.ui;
public class RegisterJFrame extends javax.swing.JFrame{
//注册界面
//以后和注册相关的所有逻辑都写在这个类中
public RegisterJFrame(){
this.setSize(488,500);
this.setVisible(true);
//设置界面的标题
this.setTitle("拼图 注册");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
}
}
3.GameJFrame
package com.woziji.ui;
public class GameJFrame extends javax.swing.JFrame {
//JFrame 界面,窗体
//子类呢? 也表示界面,窗体
//规定:GameJFrame 表示游戏的主界面
//以后和游戏相关的所有逻辑都写在这个类中
public GameJFrame() {
//设置界面的宽高
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//让界面显示出来,建议写在最后
this.setVisible(true);
}
}
2.菜单分析
快捷键:
- 按住方法名 ctrl+B 查看源码
- 选中代码块 ctrl+alt+m 重命名并抽取方法
- 单击接口名 alt+回车 重写所有方法
1.菜单制作
private void initJMenuBar() {
//创建整个的菜单对象
JMenuBar JMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象 (功能 关于我们)
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//创建选项下面的条目对象
JMenuItem replayJMenuItem = new JMenuItem("重新游戏");
JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");
JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("公众号");
//把条目添加到选项中
functionJMenu.add(replayJMenuItem);
functionJMenu.add(reLoginJMenuItem);
functionJMenu.add(closeJMenuItem);
aboutJMenu.add(accountItem);
//把选项添加到菜单中
JMenuBar.add(functionJMenu);
JMenuBar.add(aboutJMenu);
//把菜单设置到界面中
this.setJMenuBar(JMenuBar);
}
2.截止到这里的GameJFrame的代码如下
package com.woziji.ui;
import javax.swing.*;
public class GameJFrame extends javax.swing.JFrame {
//JFrame 界面,窗体
//子类呢? 也表示界面,窗体
//规定:GameJFrame 表示游戏的主界面
//以后和游戏相关的所有逻辑都写在这个类中
public GameJFrame() {
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//让界面显示出来,建议写在最后
this.setVisible(true);
}
private void initJMenuBar() {
//创建整个的菜单对象
JMenuBar JMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象 (功能 关于我们)
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//创建选项下面的条目对象
JMenuItem replayJMenuItem = new JMenuItem("重新游戏");
JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");
JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("公众号");
//把条目添加到选项中
functionJMenu.add(replayJMenuItem);
functionJMenu.add(reLoginJMenuItem);
functionJMenu.add(closeJMenuItem);
aboutJMenu.add(accountItem);
//把选项添加到菜单中
JMenuBar.add(functionJMenu);
JMenuBar.add(aboutJMenu);
//把菜单设置到界面中
this.setJMenuBar(JMenuBar);
}
private void initJFrame() {
//设置界面的宽高
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
}
}
3.功能分析
1.添加图片
坐标:
隐藏容器:取消默认居中
private void initImage() {
int number = 1;
//外循环----把内循环的代码重复执行4次
for (int i = 0; i < 4; i++) {
//内循环----表示在一行中放4个图片
for (int j = 0; j < 4; j++) {
//创建一个图片ImageIcon对象 参数:图片的路径(没加图片,意思一下得了)
//这里的图片最好命名为数字
ImageIcon icon = new ImageIcon("image\\background\\"+number+".jpg");
//创建一个JLabel对象(管理容器)
JLabel jLabel = new JLabel(icon);
//设置图片的位置
jLabel.setBounds(105*j,105*i,105,105);
//把JLabel对象添加到界面中
this.getContentPane().add(jLabel);
//添加一次后number自增1,表示下一次加载后面一张图片
number++;
}
2.截止到这里的GameJFrame的代码如下
package com.woziji.ui;
import javax.swing.*;
public class GameJFrame extends javax.swing.JFrame {
//JFrame 界面,窗体
//子类呢? 也表示界面,窗体
//规定:GameJFrame 表示游戏的主界面
//以后和游戏相关的所有逻辑都写在这个类中
public GameJFrame() {
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化图片
initImage();
//让界面显示出来,建议写在最后
this.setVisible(true);
}
private void initImage() {
int number = 1;
//外循环----把内循环的代码重复执行4次
for (int i = 0; i < 4; i++) {
//内循环----表示在一行中放4个图片
for (int j = 0; j < 4; j++) {
//创建一个图片ImageIcon对象 参数:图片的路径(没加图片,意思一下得了)
//这里的图片最好命名为数字
ImageIcon icon = new ImageIcon("image\\background\\"+number+".jpg");
//创建一个JLabel对象(管理容器)
JLabel jLabel = new JLabel(icon);
//设置图片的位置
jLabel.setBounds(105*j,105*i,105,105);
//把JLabel对象添加到界面中
this.getContentPane().add(jLabel);
//添加一次后number自增1,表示下一次加载后面一张图片
number++;
}
}
}
private void initJMenuBar() {
//创建整个的菜单对象
JMenuBar JMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象 (功能 关于我们)
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//创建选项下面的条目对象
JMenuItem replayJMenuItem = new JMenuItem("重新游戏");
JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");
JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("公众号");
//把条目添加到选项中
functionJMenu.add(replayJMenuItem);
functionJMenu.add(reLoginJMenuItem);
functionJMenu.add(closeJMenuItem);
aboutJMenu.add(accountItem);
//把选项添加到菜单中
JMenuBar.add(functionJMenu);
JMenuBar.add(aboutJMenu);
//把菜单设置到界面中
this.setJMenuBar(JMenuBar);
}
private void initJFrame() {
//设置界面的宽高
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//取消默认的居中放置,只有取消了才可以设置坐标
this.setLayout(null);
}
}
3.打乱图片
练习:打乱一维数组中的数据
int[] temperArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
要求:打乱一维数组中的数据,并按照4个一组的方式添加到二维数组中。
package com.woziji.test;
public class Test {
public static void main(String[] args) {
//需求:
//把一个一维数组中的数据:0~15,随机打乱,然后输出
//然后再按照4个一组的方式添加到二维数组中
//1.定义一个一维数组
int[] tempArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//2.随机打乱一维数组中的数据
for (int i = 0; i < tempArr.length; i++) {
//获取随机索引
int randomIndex = (int)(Math.random()*tempArr.length);
//拿着随机索引对应的值和i索引对应的值进行交换
int temp = tempArr[i];
tempArr[i] = tempArr[randomIndex];
tempArr[randomIndex] = temp;
}
//3.遍历一维数组
for (int i = 0; i < tempArr.length; i++) {
System.out.print(tempArr[i]+" ");
}
System.out.println();
//4.把一维数组中的数据按照4个一组的方式添加到二维数组中
//方法一:遍历一维数组
// int[][] arr = new int[4][4];
//for (int i = 0; i < tempArr.length; i++) {
//i/4 表示二维数组中的行索引
//i%4 表示二维数组中的列索引
// arr[i/4][i%4] = tempArr[i];
//方法二:遍历二维数组
int[][] arr = new int[4][4];
int index = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = tempArr[index];
index++;
}
System.out.println();
}
//5.遍历二维数组
for (int j = 0; j < arr.length; j++) {
for (int k = 0; k < arr[j].length; k++) {
System.out.print(arr[j][k]+" ");
}
System.out.println();
}
}
}
4.截止到这里的GameJFrame的代码如下
package com.woziji.ui;
import javax.swing.*;
public class GameJFrame extends javax.swing.JFrame {
//JFrame 界面,窗体
//子类呢? 也表示界面,窗体
//规定:GameJFrame 表示游戏的主界面
//以后和游戏相关的所有逻辑都写在这个类中
//用来管理数据
int[][] arr = new int[4][4];
public GameJFrame() {
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化数据(打乱)
initData();
//初始化图片
initImage();
//让界面显示出来,建议写在最后
this.setVisible(true);
}
private void initData() {
//1.定义一个一维数组
int[] tempArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
//2.随机打乱一维数组中的数据
for (int i = 0; i < tempArr.length; i++) {
//获取随机索引
int randomIndex = (int)(Math.random()*tempArr.length);
//拿着随机索引对应的值和i索引对应的值进行交换
int temp = tempArr[i];
tempArr[i] = tempArr[randomIndex];
tempArr[randomIndex] = temp;
}
//3.遍历一维数组
for (int i = 0; i < tempArr.length; i++) {
System.out.print(tempArr[i]+" ");
}
System.out.println();
//方法二:遍历二维数组
int index = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = tempArr[index];
index++;
}
System.out.println();
}
}
private void initImage() {
//添加图片的时候,就需要按照二维数组中管理的数据添加图片
//外循环----把内循环的代码重复执行4次
for (int i = 0; i < 4; i++) {
//内循环----表示在一行中放4个图片
for (int j = 0; j < 4; j++) {
//获取二维数组中每个索引对应的数字
int number = arr[i][j];
//创建一个图片ImageIcon对象 参数:图片的路径(没加图片,意思一下得了)
//这里的图片最好命名为数字
ImageIcon icon = new ImageIcon("image\\background\\"+number+".jpg");
//创建一个JLabel对象(管理容器)
JLabel jLabel = new JLabel(icon);
//设置图片的位置
jLabel.setBounds(105*j,105*i,105,105);
//把JLabel对象添加到界面中
this.getContentPane().add(jLabel);
//添加一次后number自增1,表示下一次加载后面一张图片
}
}
}
private void initJMenuBar() {
//创建整个的菜单对象
JMenuBar JMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象 (功能 关于我们)
JMenu functionJMenu = new JMenu("功能");
JMenu aboutJMenu = new JMenu("关于我们");
//创建选项下面的条目对象
JMenuItem replayJMenuItem = new JMenuItem("重新游戏");
JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");
JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");
JMenuItem accountItem = new JMenuItem("公众号");
//把条目添加到选项中
functionJMenu.add(replayJMenuItem);
functionJMenu.add(reLoginJMenuItem);
functionJMenu.add(closeJMenuItem);
aboutJMenu.add(accountItem);
//把选项添加到菜单中
JMenuBar.add(functionJMenu);
JMenuBar.add(aboutJMenu);
//把菜单设置到界面中
this.setJMenuBar(JMenuBar);
}
private void initJFrame() {
//设置界面的宽高
this.setSize(603,680);
//设置界面的标题
this.setTitle("拼图单机版 v1.0");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//取消默认的居中放置,只有取消了才可以设置坐标
this.setLayout(null);
}
}
4.事件
事件是可以被组件识别的操作
当你对组件干了某件事情后,就会执行对应的代码
- 事件源:按钮,图片,窗体
- 事件:某些操作
如:鼠标单击,鼠标划入 - 绑定监听:当事件源上发生了某个事件,则执行某段代码
KeyListener:键盘监听 MouseListener:鼠标监听 ActionListener:动作监听
1.ActionListener
package com.woziji.test;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class MyJFrame extends JFrame
implements ActionListener {
//创建一个按钮
JButton jb1 = new JButton("我是按钮");
//创建第二个按钮
JButton jb2 = new JButton("我是按钮2");
public MyJFrame(){
//设置宽高
this.setSize(488,430);
//设置标题
this.setTitle("事件演示");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//取消默认居中放置
this.setLayout(null);
//设置按钮的宽高
jb1.setBounds(0,0,100,50);
//给按钮添加事件
jb1.addActionListener(this);
//设置按钮的宽高
jb2.setBounds(100,0,100,50);
//给按钮添加事件
jb2.addActionListener(this);
//把按钮添加到界面上
this.add(jb1);
this.add(jb2);
//让界面展示出来
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
//对当前的按钮进行判断
//获取当前被点击的按钮
Object source = e.getSource();
if(source == jb1){
jb1.setSize(100,100);
} else if(source == jb2){
Random r = new Random();
jb2.setLocation(r.nextInt(400),r.nextInt(400));
}
}
}
package com.woziji.test;
public class Test3 {
public static void main(String[] args) {
new MyJFrame();
}
}
2.MouseListener
- 划入动作
- 单击动作
按下动作和松开动作 - 划出动作
package com.woziji.test;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class MyJFrame2 extends JFrame implements MouseListener {
//创建一个按钮
JButton jb1 = new JButton("我是按钮");
public MyJFrame2() {
//设置宽高
this.setSize(488,430);
//设置标题
this.setTitle("事件演示");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//取消默认居中放置
this.setLayout(null);
//设置按钮的宽高
jb1.setBounds(0,0,100,50);
//给按钮绑定鼠标事件
jb1.addMouseListener(this);
//把按钮添加到界面上
this.add(jb1);
//让界面展示出来
this.setVisible(true);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("单击");
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("按下不松");
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("松开");
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("划入");
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("划出");
}
}
package com.woziji.test;
public class Test3 {
public static void main(String[] args) {
//new MyJFrame();
new MyJFrame2();
}
}
3.KeyListener
package com.woziji.test;
import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyJFrame3 extends JFrame implements KeyListener {
public MyJFrame3() {
//设置宽高
this.setSize(488,430);
//设置标题
this.setTitle("事件演示");
//设置界面置顶
this.setAlwaysOnTop(true);
//设置界面居中
this.setLocationRelativeTo(null);
//设置界面的关闭方式
this.setDefaultCloseOperation(3);
//取消默认居中放置
this.setLayout(null);
//给整个窗体绑定键盘事件
//调用者this:本类对象,当前界面的对象,表示我要给整个界面添加监听
//参数this:当事件被触发后,会执行本类中的对应代码
this.addKeyListener(this);
//让界面展示出来
this.setVisible(true);
}
@Override
public void keyTyped(KeyEvent e) {
System.out.println("这个不重要");
}
//细节1:
//如果我们按下一个按键没有松开,那么会重复触发keyPressed方法
//细节2:
//键盘里那么多按键,如何进行区分
//键盘上的每一个按键都有一个编号
@Override
public void keyPressed(KeyEvent e) {
System.out.println("按下不松");
}
@Override
public void keyReleased(KeyEvent e) {
System.out.println("松开");
//获取键盘上的每一个按键的编号
int code = e.getKeyCode();
if(code == 32){
System.out.println("按下的是空格键");
} else if(code == 65){
System.out.println("按下的是A键");
}
}
}
package com.woziji.test;
public class Test3 {
public static void main(String[] args) {
//new MyJFrame();
//new MyJFrame2();
new MyJFrame3();
}
}