主界面
小练习1:
一、三个界面的设置1:创建窗体
1、将三个主界面分开为三个类,每个类都去继承JFrame这个类,使得每个类都可以使用创建页面功能
2、对每个类进行空参构造,在空参构造里面进行窗体属性的赋值
3、创建一个App类并导入上面三类,统一进行窗口创建操作,仅使用空参构造即可
二、三个界面的设置2:更新窗体的细节属性(标题、窗口在页面置顶、界面居中生成位置、设置关闭模式)
为啥关闭模式是数字3:由源码得,这里设置了一个接口,所以也可以写成WindowConstants.EXIT_ON_CLOSE:
0指点了窗口关闭标志没反应;
1是默认操作,可省略;
2是当所有窗口关闭后,虚拟机才停止,但必须所有窗体都写了这个操作时才生效;
3是点了关闭其中一个窗体,就停止运行虚拟机
三、菜单制作:最后需要利用setJMenuBar()将JMenuBar可视化
示例代码:
运行效果图:
四、添加图片(一张,主看思路)
利用JLabel添加,图片默认添加在正中央
示例代码:建立imageIcon对象,建立Jlable管理容器对象添加imageIcon对象,最后添加到界面中
坐标:以窗体左上角为基准,左边x,右边y。
图片默认放在正中央,怎么取消? 将图片传给getContentPane这个隐藏容器,后设置setLayout(null)取消默认,才能跟着xy坐标走。
getContentPane对象不需要自己创建,在创建JFrame时会自己创建
xy坐标公式:jlabel对象.setBounds(x:,y:,width:,height:);
1.取消默认
2.设置坐标,传给窗体隐藏器
五、循环添加图片(全部)
在添加number到文件路径时,直接加number会被当作字符串,需要利用加号添加:
\\"+number+".jpg"
//利用循环建立添加所有图片,第16张找不见会自动添加白色
private void initImage() {
int number=1;
//外循环:把内循环重复执行4次
for (int i = 0; i < 4; i++) {
//内循环:一行添加4张
for (int j = 0; j < 4; j++) {
//建立imageIcon对象、JLabel对象
JLabel jLabel = new JLabel(new ImageIcon("E:\\CODE ENVIRONMENT\\JAVA\\JAVACODE\\Game\\image\\animal\\animal3\\"+number+".jpg"));
//设置图片坐标,x,y=0,表示在窗体左上角
jLabel.setBounds(105*j,105*i,105,105);
//把管理容器添加到界面,图片按照.setBounds传递的坐标位置
this.getContentPane().add(jLabel);
number++;
}
}
}
6.打乱图片(利用二维数组)
6.1 把一维数组统一放入二维数组
将打乱的一维数组添加到二维数组:
打乱过程:
int []tempArr={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
Random r =new Random();
int temp = 0;
for (int i = 0; i < tempArr.length; i++) {
int index = r.nextInt(16);
temp = tempArr[i];
tempArr[i]=tempArr[index];
tempArr[index]=temp;
}
方法1:遍历一维数组tempArr再赋值
int [][]data =new int[4][4];
for (int i = 0; i < tempArr.length; i++) {
//i/4: i = 0, i/4 = 0; i = 1, i/4 = 0;i = 2, i/4 = 0;i = 3, i/4 = 0....
//i%4: i = 0, i%4 = 0; i = 1, i%4 = 1; i = 2, i%4 = 2...
data[i/4][i%4]=tempArr[i];
}
data[i/4][i%4]很巧妙,保证按照i=1,2,3,4时[0,0] [0,1],[0,2],[0,3] ;当i>=5时就会切换到二维数组第二行,以此类推。
方法2:遍历二维数组再赋值,需要单独设立索引,遍历tempArr
int [][]data =new int[4][4];
int index = 0;
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
data[i][j]= tempArr[index];
index++;
}
}
6.2 运用进游戏:
1.现在建立全局二维数组
int [][]data = new int[4][4];
2.加入方法:初始化数据(打乱图片),并在空参构造中调用
private void initData(){
int []tempArr={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
Random r =new Random();
int temp = 0;
for (int i = 0; i < tempArr.length; i++) {
int index = r.nextInt(16);
temp = tempArr[i];
tempArr[i]=tempArr[index];
tempArr[index]=temp;
}
for (int i = 0; i < tempArr.length; i++) {
data[i/4][i%4]=tempArr[i];
}
}
3.按照二维数组编号顺序(num),加载图片的位置从而实现打乱
private void initImage() {
//外循环:把内循环重复执行4次
for (int i = 0; i < 4; i++) {
//内循环:一行添加4张
for (int j = 0; j < 4; j++) {
//获取现在所要添加图片的序号
int num =data[i][j];
//建立imageIcon对象、JLabel对象
JLabel jLabel = new JLabel(new ImageIcon("D:\\WHY\\JAVA code\\Game\\image\\animal\\animal3\\"+num+".jpg"));
//设置图片坐标,x,y=0,表示在窗体左上角
jLabel.setBounds(105*j,105*i,105,105);
//把管理容器添加到界面,图片按照.setBounds传递的坐标位置
this.getContentPane().add(jLabel);
}
}
}
4.效果:打乱后每次生成位置随机
7.事件
ActionListener(两种练习对应的方法和细节针对三种监听模式都适用)
动作监听只能监听鼠标左键点击和空格
练习1:利用匿名方法类创建动作监听操作
JBotton是按键对象,创建其对象时,后面括号可以写他的按钮的显示名字
动作监听:
jb.addActionListener();括号里面需要的是addActionListener的实体类,但却只是用一次,考虑利用匿名方法类解决这一问题
setSize(int width, int height):定义控件的大小,有两个参数,分别对应宽度和高度;
setLocation(int x, int y):将组件移到新位置,用x 和 y 参数来指定新位置的左上角
setBounds(int x, int y, int width, int height):四个参数,既定义组件的位置,也定义控件的大小; 其实它就是上面两个函数的功能的组合
package test;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class test2 {
public static void main(String[] args) {
//页面初始化
JFrame jF = new JFrame();
jF.setSize(603,600);
jF.setTitle("事件演示");
jF.setAlwaysOnTop(true);
jF.setLocationRelativeTo(null);
jF.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jF.setLayout(null);
//设置按钮
JButton jb =new JButton("点我啊");
Random r = new Random();
jb.setBounds(0,0,100,50);
//利用匿名类增加监听
jb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("你们不要点我啦!");
// jb.setSize(100,100);
jb.setBounds(r.nextInt(500),r.nextInt(500),100,50);
}
});
//将按钮添加到页面
jF.getContentPane().add(jb);
jF.setVisible(true);
}
}
练习2:利用利用继承和添加接口创建动作监听操作
why:this可以调用方法,看疑惑点笔记
成员类:
//获取当前被操作的按钮对象
Object s = e.getSource();
package test;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
public class test3 extends JFrame implements ActionListener {
JButton jb1 =new JButton("你点我啊!");
JButton jb2 =new JButton("你点不着我吧!");
public test3(){
initJFrame();
initJButton();
//显示整体窗体(true是显示,false是关闭),写在最后
this.setVisible(true);
}
public void initJFrame() {
//设置尺寸(单位是尺寸)
this.setSize(603,680);
//设置标题
this.setTitle("事件演示");
//设置窗口在页面置顶
this.setAlwaysOnTop(true);
//设置界面居中生成位置,利用null
this.setLocationRelativeTo(null);
//设置关闭模式
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//取消加载图片的默认居中
this.setLayout(null);
}
public void initJButton(){
//给按钮设置位置和宽高
jb1.setBounds(0,0,100,50);
//给按钮添加事件
jb1.addActionListener(this);
jb2.setBounds(0,100,120,50);
jb2.addActionListener(this);
this.getContentPane().add(jb1);
this.getContentPane().add(jb2);
}
@Override
public void actionPerformed(ActionEvent e) {
//获取当前被操作的按钮对象
Object s = e.getSource();
if (s==jb1){
jb1.setSize(200,100);
}else if (s==jb2){
Random r =new Random();
jb2.setLocation(r.nextInt(500),r.nextInt(500));
}
}
}
测试类:
public class test3_test {
public static void main(String[] args) {
test3 t =new test3();
}
}
MouseListener
KeyListerner(快捷键的使用):第三个方法不常用
细节:标号不是ASCII码表,e.getKeyCode()获取的是每一个按键的标号
8.美化页面:先加载的图片在上方,后加载的图片放在下方
给图片创建内边框:0,1 / BevelBoeder.LOWERED, BevelBoeder.RAISED
//加入背景图片
JLabel j = new JLabel(new ImageIcon("image\\background.png"));
j.setBounds(40,40,508,560);
this.getContentPane().add(j);
路径美化: 利用相对路径,从本项目文件夹下一级开始写,或者在本文件夹前加
“..\\”
9.移动图片
实际上是对空白格子进行上下左右移动操作,所以要知道空白格子的位置:
小结:
10.显示完整图片
11、优化路径,方便后期修改
String path ="..\\Game\\image\\animal\\animal3\\";
JLabel jLabel = new JLabel(new ImageIcon(path+num+".jpg"));
12、作弊码,一键还原图片
13、判断胜利标准
先加载的图片在上方,后加载的图片放在下方
14、统计步数:
1.先在成员变量设置步数变量
2.在图像初始化设置显示页面
3.在监听方法中,对上下左右移动操作进行step++的操作
15.加入重新游戏、关闭游戏、关于我们等功能
首先要加入动作监听,绑定事件:
重新游戏:
关闭游戏:
else if (s==CloseItem){
System.exit(0);
}