代码完整,按照类建立项目即可
board类
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionListener;
public class Board extends JPanel implements BoardDraw{
//定义一个记录棋子位置的二维数组
public int[][] weiZhi = new int[15][15];
//定义一个画笔
public Graphics g;
public static void main (String args[]){
Board gb = new Board();//首先初始化一个五子棋的对象
//然后初始化桌面
gb.initB();
}
public void initB(){
JFrame jf = new JFrame();//1、新建一个Frame
jf.setTitle("five in a raw");//给这个frame一个名字
jf.setSize(800,600);//设置frame大小
jf.setLocationRelativeTo(null);//这个就是设置窗口位置,要是没有就默认是中间显示
jf.setDefaultCloseOperation(3);//这里就是点关闭就是关闭
//然后就开始设置布局,这里用的是boarder的那种
jf.setLayout(new BorderLayout());
//这种设置方法可以重复使用尺寸,也可以不用下面这种,在每个设置尺寸的地方手动打尺寸
//设置一些固定大小的框框
Dimension d1 = new Dimension(150,250);//设置右边的框框的大小
Dimension d2 = new Dimension(140,40);//设置右边框框内的按键大小
Dimension d3 = new Dimension(500,150);//设置左边大小
//setPreferredSize(d3);//设置棋盘部分
//这里设置大小也可以换成,setSize;setSize是设定的固定大小,而setPreferredSize仅仅是设置最好的大小,
// 这个不一定与实际显示出来的控件大小一致(根据界面整体的变化而变化
//this.setSize(500,450);//类要是不extends JPanel就用不了this这种写法
this.setPreferredSize(d3);
this.setBackground(Color.gray);//设置背景色
jf.add(this,BorderLayout.CENTER);//布局是放在中间
//现在设置右边的界面
JPanel jp =new JPanel();//新建一个Panel
jp.setPreferredSize(d1);//设置大小
jp.setBackground(Color.white);//设置颜色
jf.add(jp,BorderLayout.EAST);//把panel加到之前的那个frame上,并且放在右边
jp.setLayout(new FlowLayout());//顺序排列
//把按钮放在JPanel上
String[] buttonName={"start","undo","give up"};//设置按钮名字
JButton[] button = new JButton[3];//新建按钮对象数组
//设置按钮大小、并放到右侧
for(int i =0;i<buttonName.length;i++){
button[i]=new JButton(buttonName[i]);//分别把每个按钮命名
button[i].setPreferredSize(d2);//设置按钮大小
jp.add(button[i]);//将按钮添加到Panel上
}
//监控按钮
//注意这里直接添加this会提示需要implements BoardDraw项,所以得去类那添加一下
ButtonListener buttonListener = new ButtonListener(this);
for (int i=0;i<button.length;i++){
button[i].addActionListener(buttonListener);//这里对每个按键进行了注册
}
//显示图像
jf.setVisible(true);
}
//画棋子
//重写一下paint方法
public void paint(Graphics g){
super.paint(g);
//重绘paint
g.setColor(Color.black);
for (int i=0;i<row;i++){
g.drawLine(x,y+i*size,x+row*size,y+size*i);//java画布是左上角(0,0),y轴↓--→x轴
}
for (int j =0;j<col;j++){
g.drawLine(x+j*size,y,x+size*j,y+col*size);
}
//这里,需要把棋子的绘画过程也放在这里,注意要定义一个位置的二维数组,方便记录没有下过的位置
for (int i=0;i<row;i++){
for (int j =0;j<col;j++){
if (weiZhi[i][j]==1){
int qi_x=size*i+20;
int qi_y=size*j+20;
g.setColor(Color.black);
g.fillOval(qi_x,qi_y,20,20);
}
else if(weiZhi[i][j]==2){
int qi_x=size*i+20;
int qi_y=size*j+20;
g.setColor(Color.WHITE);
g.fillOval(qi_x,qi_y,20,20);
}
}
}
}
}
按键监听
ButtonListener
import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.MouseListener;
//因为不止要实现按键监听,还需要对board进行绘制,所以不直接用ActionListener,而是新建一个类来应用board和按键的接口
public class ButtonListener implements BoardDraw, ActionListener {
public Board bd;
//ButtonListener的构造函数
public ButtonListener(Board bd){
this.bd =bd;//就把这个看成python中的self吧
}
//当有操作发生的时候,界面发生的变化
@Override
public void actionPerformed(ActionEvent e) {
//首先判断按了哪个
if (e.getActionCommand().equals("start")){
//当按了开始的时候,要监听的就是棋盘,把棋盘放进去
FrameListener fl =new FrameListener();
fl.setGraphs(bd);//画笔设定
//监听鼠标
bd.addMouseListener(fl);
}
}
}
棋盘监听
FrameListener
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.ActionEvent;
import java.awt.Graphics;
import java.awt.Color;
public class FrameListener implements BoardDraw,MouseListener{
public Board bd;
public int turn_flag=0; //用来标记到黑棋还是白棋走
public void setGraphs(Board bd){
this.bd=bd;
}
@Override
public void mouseClicked(MouseEvent e) {
//获得鼠标位置
int X=e.getX();
int Y=e.getY();
//放到交点处
int countx = (X/size)*size;
int county =(Y/size)*size;
//计算是第几个格子的
int row = (countx-x)/size;
int cl = (county-y)/size;
//画笔画在bd画布上
Graphics gg = bd.getGraphics();
//判断落子位置有没有棋子
if (bd.weiZhi[row][cl]!=0){
System.out.println("这已经有棋子了");
}
else {
if (turn_flag==0){
gg.setColor(Color.BLACK);
gg.fillOval(countx,county,size,size);
this.bd.weiZhi[row][cl]=1;
turn_flag=1;
}
else {
gg.setColor(Color.WHITE);
gg.fillOval(countx,county,size,size);
this.bd.weiZhi[row][cl]=2;
turn_flag=0;
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
接口
public interface BoardDraw {
int x=20,y=20,size=40,row=15,col=15;//初始化棋子区域的一些参数
//x:棋盘的原点横坐标
//y:棋盘原点纵坐标
//size:格子的尺寸,还有棋子的尺寸
//row:行数
//col:列数
}