共计 9193 个字符,预计需要花费 23 分钟才能阅读完成。
为了深刻学习 Java 中 GUI 与事件处理机制,利用 java 中的 GUI 与事件处理机制等性能实现围棋小游戏。
效果图
一、概述
1、GUI 是指图形用户界面也称图形用户接口,在 Java 中是进行人机交互的窗口,在这个窗口中用户能够实现应用程序提供的所有性能。事件处理机制在上一篇文章中有具体介绍,这里不多阐明。
二、设计
(自己的设计思维是:先设计一个整体的框架,再往设计好的框架中退出组件,并一步步的进行调试,争取每步都在正确的路线上,各代码之间互相交融。)
1、逻辑设计
1)、首先创立一个顶级窗口容器类 myframe,作为整体的框架。
2)、而后创立规定类 Rule,退出到框架中
3)、而后创立棋盘类 ChessPad,退出到框架中,再在棋盘类中增加具体的组件,比如说一个从新开始按钮和两个用于提醒作用的文本框,如上效果图。
4)、再创立黑棋子类 Chess_black 和白棋子类 Chess_white,退出到棋盘类中
5)、最初创立实现鼠标监听事件类 Listen,用于实现各组件的产生的事件。
6)、最初创立一个主类 mains,用于启动程序。
留神:这里其实是有三个容器,一个顶级窗口容器属于最顶级的,一个规定类容器(因为这里我是用继承 JPanel 面板容器实现的)和一个棋盘类容器(还是用继承 JPanel 面板容器实现的)。我把各种组件都是增加到棋盘类容器中的,所以当实现组件产生的事件时,其实是在棋盘类容器中进行各种操作的,而不是在顶级窗口容器中。
2、代码实现
(1)、这里通过创立一个窗口类 myfame 继承 JFrame 类来创立顶级窗口容器。留神:这里的窗口类布局管理器为空布局。
package 单机围棋;
import javax.swing.JFrame;
class myframe extends JFrame// 窗口类
{
private static final long serialVersionUID=2l;
ChessPad chessPad=new ChessPad();
// 办法定义
public void display()// 窗口设置
{setTitle("围棋");
setLayout(null);// 设置容器布局为空布局
setSize(570,560);// 窗口大小
/***********************************************/
Rule rule=new Rule();// 规定面板类对象
add(rule);
rule.setBounds(60, 20, 440, 30);// 设置规定面板类在窗口中的地位和大小
/***********************************************/
ChessPad chessPad=new ChessPad();// 棋盘面板类对象
add(chessPad);
chessPad.setBounds(60, 60, 440, 440);// 设置棋盘面板类在窗口中的地位和大小
/***********************************************/
setVisible(true);// 窗口为可见
setResizable(false);// 不可扭转窗口大小
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
(2)、通过创立一个 Rule 类继承 JPanel 面板容器实现规定面板,再退出到顶级窗口容器中,并设置在窗口中的地位。
package 单机围棋;
import java.awt.Color;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Rule extends JPanel// 规定面板类
{
private static final long serialVersionUID=2l;
// 属性定义
JLabel label;// 标签
// 办法定义
public Rule()
{setBackground(Color.orange);// 面板色彩
setSize(440, 30);// 面板大小
label=new JLabel("单击左键下棋子,双击左键吃棋子,落子无悔!请谨慎!");
add(label);
}
}
(3)、通过创立棋盘类 ChessPad 继承 JPanel 面板容器实现棋盘,并在棋盘容器中退出从新开始组件,一个标签组件,和两个文本框组件。
package 单机围棋;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ChessPad extends JPanel// 棋盘面板类
{
private static final long serialVersionUID=3l;
// 属性定义
JButton button;// 按钮
JTextField text1,text2;// 文本框
JLabel label;// 标签
Listen listen=new Listen();// 创立监听器对象
// 办法定义
ChessPad()// 构造方法
{setSize(440,440);// 棋盘面板大小
setLayout(null);// 棋盘布局为空
setBackground(Color.orange);// 面板色彩
button=new JButton("从新开始");
add(button);
button.addMouseListener(listen);// 在按钮中增加监听器
button.setBounds(3, 10, 85, 20);
text1=new JTextField("请黑棋下子");
add(text1);
text1.addMouseListener(listen);// 在文本框 1 中增加监听器
text1.setBounds(92, 10, 100, 20);
label=new JLabel("提示框:");
add(label);
label.setBounds(214, 10, 60, 20);
text2=new JTextField("游戏开始,请黑棋先下子");
add(text2);
text2.setBounds(257, 10, 180, 20);// 在文本框 2 中增加监听器
listen.set1(button, this);// 把按钮实例对象和棋盘实例对象传入实现监听事件类的中
listen.set2(text1, text2,label);// 把文本框实例对象和标签实例对象传入实现监听事件类的中
addMouseListener(listen);// 在棋盘类中增加监听器,留神这里是吧整个棋盘面板作为事件源
}
@Override
public void paintComponent(Graphics g)// 画线, 棋盘行列间距为 40 像素,行列为 19
{super.paintComponent(g);
for(int i=40;i<=400;i=i+20)
g.drawLine(40, i, 400, i);
for(int j=40;j<=400;j=j+20)
g.drawLine(j, 40, j, 400);
// 在棋盘的指定地位绘制实心圆,留神左上角坐标不是圆心坐标
g.fillOval(97, 97, 6, 6);
g.fillOval(337, 97, 6, 6);
g.fillOval(97, 337, 6, 6);
g.fillOval(337, 337, 6, 6);
g.fillOval(217, 217, 6, 6);
}
public void paintchess()// 在棋盘上画棋子的办法
{Graphics p=getGraphics();
p.fillOval(96, 96, 10, 10);
}
}
(4)、创立黑棋子类,并实现 MouseListener 接口用来在本身类中实现”双击黑棋子进行吃黑棋子“的性能。这里的黑棋是通过继承 JPanel 容器实现的,也就是说黑棋子其实也是个面板容器(同样白棋子也是)。
package 单机围棋;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
public class Chess_black extends JPanel implements MouseListener// 黑棋子类继承面板容器,本身实现鼠标点击事件
{
public static final long serialVersionUID=03l;// 序列号
ChessPad chessPad;
public void get(ChessPad chessPad)// 传入棋盘实例对象
{this.chessPad=chessPad;}
public Chess_black()// 定义黑棋子面板容器大小,并增加鼠标事件监听器
{setSize(20,20);
addMouseListener(this);
}
@Override
public void paint(Graphics p)// 定义黑棋子色彩宽高
{p.setColor(Color.black);
p.fillOval(0, 0, 20, 20);
}
@Override
public void mouseClicked(MouseEvent e)// 实现鼠标监听事件
{if (e.getClickCount()>=2)// 如果鼠标间断点击了两下或以上
{if(e.getSource()==this)// 如果鼠标点击的是黑棋子组件
{chessPad.remove(this);// 在棋盘面板容器中移除被点击的黑棋子组件
chessPad.repaint();// 刷新棋盘, 如果不刷新,则会显示异样}
}
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}}
(5)、应用与创立黑棋子类雷同的办法创立白棋子 Chess_white。
package 单机围棋;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
public class Chess_white extends JPanel implements MouseListener
{
public static final long serialVersionUID=02l;// 序列号
ChessPad chessPad;
public void get(ChessPad chessPad)
{this.chessPad=chessPad;}
public Chess_white()
{setSize(20,20);
addMouseListener(this);
}
@Override
public void paint(Graphics p)// 重写 paint 办法画好白棋子对象色彩和大小。该办法为在面板容器中应用的用来设计面板款式的办法,// 所以只有调用该办法所在类的容器对象,就能够显示该办法所设计的容器的样子
{p.setColor(Color.white);
p.fillOval(0, 0, 20, 20);
}
@Override
public void mouseClicked(MouseEvent e)
{if (e.getClickCount()>=2)
{if(e.getSource()==this)
{chessPad.remove(this);
chessPad.repaint();}
}
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}}
(6)、鼠标监听事件类 Listen,用于实现各组件相应的性能。
package 单机围棋;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Listen extends MouseAdapter// 实现鼠标点击事件
{
JButton button;
ChessPad chessPad;
JTextField text1,text2;
JLabel label;
int x,y;
int color=0;// 让黑棋先落子
Chess_black chessblack;
Chess_white chesswhite;
public void set1(JButton button,ChessPad chessPad)// 传入组件实例对象,并初始化
{
this.button=button;
this.chessPad=chessPad;
}
public void set2(JTextField text1,JTextField text2,JLabel label)// 传入组件实例对象,并初始化
{
this.text1=text1;
this.text2=text2;
this.label=label;
}
@Override
public void mouseClicked(MouseEvent e)// 鼠标在组件上单击 (按下并开释) 时调用该办法。{if(e.getSource()==button)// 从新开始事件的实现
{chessPad.removeAll();// 删除容器中所有组件
chessPad.repaint();// 刷新容器显示界面
// 从新往容器中增加组件
chessPad.add(button);
chessPad.add(text1);
chessPad.text1.setText("请黑棋下子");
chessPad.add(label);
chessPad.add(text2);
chessPad.text2.setText("从新开始了, 请黑棋先下子");
color=0;// 色彩从新设置为 0,从新从黑棋开始下
}
// 失去鼠标在容器中的坐标
x=e.getX();
y=e.getY();
// 失去坐标在棋盘上的行列地位
int a=(x+9-20)/20;// 行地位
int b=(y+9-20)/20;// 列地位
if(e.getSource()==chessPad)// 在棋盘上下棋事件的实现
{if(x<35||y<35||x>405||y>405)// 判断鼠标下棋地位,若超出棋盘地位则不落子
{chessPad.text2.setText("别乱点!棋只能下在棋盘下面!");// 鼠标超出棋盘地位,不落子
}
else// 鼠标在棋盘中,开始落子
{if(color==1)// 若棋子色彩为 1,则落白子
{chesswhite=new Chess_white();// 定义白棋子组件实例对象
chesswhite.get(chessPad);
chessPad.add(chesswhite);// 往棋盘容器中增加白子
chesswhite.setBounds(a*20+10, b*20+10, 20, 20);// 白子落子地位
chessPad.text1.setText("请黑棋下子");
chessPad.text2.setText(null);
color--;// 棋子色彩设置 0,管制下一步落子色彩为黑子
}
else if(color==0)// 若棋子色彩为 0,则落黑子
{chessblack=new Chess_black();// 定义黑棋子组件的实例对象
chessblack.get(chessPad);
chessPad.add(chessblack);// 往棋盘容器中增加黑子
chessblack.setBounds(a*20+10, b*20+10, 20, 20);// 黑子落子地位
chessPad.text1.setText("请白棋下子");
chessPad.text2.setText(null);
color++;// 棋子色彩设置为 1,管制下一步落子为白子
}
}
}
}
}
(7)、鼠标监听事件类 Listen 创立
package 单机围棋;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class Listen extends MouseAdapter// 实现鼠标点击事件
{
JButton button;
ChessPad chessPad;
JTextField text1,text2;
JLabel label;
int x,y;
int color=0;// 让黑棋先落子
Chess_black chessblack;
Chess_white chesswhite;
public void set1(JButton button,ChessPad chessPad)// 传入组件实例对象,并初始化
{
this.button=button;
this.chessPad=chessPad;
}
public void set2(JTextField text1,JTextField text2,JLabel label)// 传入组件实例对象,并初始化
{
this.text1=text1;
this.text2=text2;
this.label=label;
}
@Override
public void mouseClicked(MouseEvent e)// 鼠标在组件上单击 (按下并开释) 时调用该办法。{if(e.getSource()==button)// 从新开始事件的实现
{chessPad.removeAll();// 删除容器中所有组件
chessPad.repaint();// 刷新容器显示界面
// 从新往容器中增加组件
chessPad.add(button);
chessPad.add(text1);
chessPad.text1.setText("请黑棋下子");
chessPad.add(label);
chessPad.add(text2);
chessPad.text2.setText("从新开始了, 请黑棋先下子");
color=0;// 色彩从新设置为 0,从新从黑棋开始下
}
// 失去鼠标在容器中的坐标
x=e.getX();
y=e.getY();
// 失去坐标在棋盘上的行列地位
int a=(x+9-20)/20;// 行地位
int b=(y+9-20)/20;// 列地位
if(e.getSource()==chessPad)// 在棋盘上下棋事件的实现
{if(x<35||y<35||x>405||y>405)// 判断鼠标下棋地位,若超出棋盘地位则不落子
{chessPad.text2.setText("别乱点!棋只能下在棋盘下面!");// 鼠标超出棋盘地位,不落子
}
else// 鼠标在棋盘中,开始落子
{if(color==1)// 若棋子色彩为 1,则落白子
{chesswhite=new Chess_white();// 定义白棋子组件实例对象
chesswhite.get(chessPad);
chessPad.add(chesswhite);// 往棋盘容器中增加白子
chesswhite.setBounds(a*20+10, b*20+10, 20, 20);// 白子落子地位
chessPad.text1.setText("请黑棋下子");
chessPad.text2.setText(null);
color--;// 棋子色彩设置 0,管制下一步落子色彩为黑子
}
else if(color==0)// 若棋子色彩为 0,则落黑子
{chessblack=new Chess_black();// 定义黑棋子组件的实例对象
chessblack.get(chessPad);
chessPad.add(chessblack);// 往棋盘容器中增加黑子
chessblack.setBounds(a*20+10, b*20+10, 20, 20);// 黑子落子地位
chessPad.text1.setText("请白棋下子");
chessPad.text2.setText(null);
color++;// 棋子色彩设置为 1,管制下一步落子为白子
}
}
}
}
}
(8)、主类 mains 创立,最初启动主类既可启动程序,进行围棋游戏啦!!
package 单机围棋;
public class mains
{public static void main (String []args)
{new myframe().display();}
}
三、总结
通过这次小游戏的实现,理解把握 GUI 图形界面的设计,并学习界面中各组件与事件处理机制的性能交互实现。这里次要是使用到了 JPanel 容器(JPanel 又称面板,是 Java 中最罕用的轻量级容器之一,其默认布局管理器是 FlowLayout(流式布局管理器)。JPanel 能够包容其余组件,但其自身不可见,须要退出到顶级容器中能力存在,因而也称为两头容器,JPanel 之间能够嵌套,对组件进行组合。)来实现界面的设计。当然也能够应用其余的组件或者容器来进行界面的设计,并且也能够增加其余组件来实现相应更简单的性能,但因为图形界面的设计并不是 Java 的强项,也因为 GUI 倒退的停滞,这里不对 GUI 作深刻的理解。本文旨在学习 Java 事件处理机制以及事件处理机制实现性能的过程,并对设计模式有肯定的学习和理解,并标准代码的实现,给自己本人找准一种学习的思路,也心愿能给读者带来帮忙。
Java 路漫漫,唯有君作伴~