以九宫格小游戏为例
九宫格有九个小块,其中一个空块,与空块相邻的小块可以和空块交换位置。实现键盘响应和鼠标响应
布局
直接绘图的方式
新建一个Board类,Board类有个List用于放置小块,九宫格的第一行是list的前3个,以此类推。
//根据小块的的位置得出小块在Board中的横坐标
public int getX(){
int xloca = location;
if(location >2 && location <=5){
xloca -= 3;
}else if(location > 5){
xloca -= 6;
}
return (xloca)*Action.GAME_WIDTH/3;
}
//根据小块的的位置得出小块在Board中的横坐标
public int getY(){
int yloca = 0;
if(location >2 && location <=5){
yloca = 1;
}else if(location > 5){
yloca = 2;
}
return yloca*Action.GAME_HEIGHT/3 + Action.TITLE_SIZE;
}
block需要通过getX()和getY()方法来获取block在board中的坐标,例如block的位置为0,那么坐标就为(0,0),位置为1坐标为(位置*小块宽度,0),当位置大于2时,也就是第二行,那么纵坐标就为1。
添加组件方式
Board类继承JPanel,Block类继承JLabel,因为继承了Component类,所以Board通过JPanel的add()方法添加Block小块,这种方式不需要判断不同位置的小块在Board中的坐标,使用JPanel的布局管理器,设置为3*3的网格布局就可以实现。
绘图
直接绘图的方式
list中的block交换顺序后需要刷新界面,响应完成后执行update()方法,update()方法再依次调用block的draw()方法。
public void draw(Graphics g){
//绘制小块
g.setColor(getColor());
g.fillRect(getX(), getY(), Action.GAME_HEIGHT/3, Action.GAME_WIDTH/3);
//绘制小块边框
g.setColor(Color.white);
g.drawRect(getX(), getY(), Action.GAME_HEIGHT/3, Action.GAME_WIDTH/3);
//绘制小块上的数字
g.setColor(Color.yellow);
g.setFont(new Font(null,Font.PLAIN,50));
g.drawString(""+number, getX()+Action.GAME_HEIGHT/6, getY()+Action.GAME_WIDTH/6);
moreDraw(g);
}
添加组件方式
不需要编写绘图的方法,只需要设置父类JLabel的背景颜色和text显示文字即可,小块之间执行完交换顺序的操作后需要刷新界面,响应完成后执行Board类的父类Jpanel的revalidate()方法,revalidate()会对board中的组件进行重新布局。
自适应大小
直接绘图的方式
当调整窗口的大小时,需要添加窗口改变事件来刷新页面,保证窗口内的内容同比例增大。
添加组件方式
会自动填充满窗体。
鼠标事件的响应
直接绘图的方式
因为block没有继承JLabel,所以自然不能添加鼠标监听,那么只能在JFrame中添加鼠标监听事件,当鼠标点击某一个方块时,是窗口响应了这个点击事件,所以窗口就要根据点击的坐标判断是哪一个方块被点击。
添加组件方式
因为block继承JLabel,那么就可以为每一个block添加鼠标监听,当鼠标点击某一个方块时,这个方块就可以直接响应点击事件。
总结:
绘图方式更加灵活,继承组件方式固然提供了许多便利,但是相应的限制也更多。