(以下内容全部来自上述课程)
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 JFrameimplements 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);}@Overridepublic 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);}@Overridepublic void mouseClicked(MouseEvent e) {System.out.println("单击");}@Overridepublic void mousePressed(MouseEvent e) {System.out.println("按下不松");}@Overridepublic void mouseReleased(MouseEvent e) {System.out.println("松开");}@Overridepublic void mouseEntered(MouseEvent e) {System.out.println("划入");}@Overridepublic 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);}@Overridepublic void keyTyped(KeyEvent e) {System.out.println("这个不重要");}//细节1://如果我们按下一个按键没有松开,那么会重复触发keyPressed方法//细节2://键盘里那么多按键,如何进行区分//键盘上的每一个按键都有一个编号@Overridepublic void keyPressed(KeyEvent e) {System.out.println("按下不松");}@Overridepublic 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();}
}