基于第二次数独游戏,添加GUI界面
高级软件工程第三次作业:基于第二次数独游戏,添加GUI界面。GUI界面代码如下:
package firstGui; import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import javax.swing.*; import org.eclipse.swt.widgets.ExpandItem; public class sudokuGui2 { private JFrame frame;
static int[][] cellsAnswer = new int[9][9];
static int[][] cells = new int[9][9];
static int level = 0; //表示游戏等级 public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
sudokuGui2 window = new sudokuGui2();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
} /**
* 构造方法
*/
public sudokuGui2() {
initialize();
} /**
* 初始化窗体
*/
private void initialize() { frame = new JFrame("数独游戏");
// setBounds(x,y,width,height);
// x:组件在容器X轴上的起点 y:组件在容器Y轴上的起点 width:组件的长度 height:组件的高度
frame.setBounds(100, 100, 900, 680);
frame.setResizable(false); //设置窗口是否可变大小
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null); //要设置Jpanel的位置与大小,要先关闭frame的布局管理器
JPanel panel = new JPanel();
panel.setBounds(80, 60, 500, 500);
frame.getContentPane().add(panel); Color c1 = new Color(253, 237, 237);
Color c2 = new Color(254, 254, 254); JTextField[][] chessBoard = new JTextField[9][9];
sudokuV2_modify shudu = new sudokuV2_modify(level);
cellsAnswer = shudu.getAnswer(); // 从sudokuV2_modify获取数独的答案
cells = shudu.getChess(); // shudu.show(cellsAnswer);
// System.out.println();
// shudu.show(cells); /**
* 设置棋盘的初始状态
*/
panel.setLayout(new GridLayout(9, 9));
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
// 设置JTextField的内容
chessBoard[i][j] = new JTextField();
chessBoard[i][j].setFont(new Font("TimesRoman", Font.PLAIN, 26));
chessBoard[i][j].setHorizontalAlignment(JTextField.CENTER);
if (cells[i][j] == 0) {
chessBoard[i][j].setForeground(Color.gray);
} else {
chessBoard[i][j].setText(Integer.toString(cells[i][j]));
chessBoard[i][j].setFocusable(false); // 设置是否可获得焦点
// chessBoard[i][j].setEnabled(false); //设置是否处于激活状态
} /** 设置3*3九宫格的背景颜色 */
if ((i / 3 == 0 && j / 3 == 0) || (i / 3 == 1 && j / 3 == 1) || (i / 3 == 2 && j / 3 == 2)
|| (i / 3 == 0 && j / 3 == 2) || (i / 3 == 2 && j / 3 == 0)) {
chessBoard[i][j].setBackground(c1);
} else {
chessBoard[i][j].setBackground(c2);
} chessBoard[i][j].setVisible(true);
panel.add(chessBoard[i][j]);
panel.setVisible(true);
}
} JButton commit = new JButton("提交答案");
commit.setBounds(610, 440, 120, 30);
commit.setBorder(BorderFactory.createRaisedBevelBorder());
commit.setBackground(c1);
commit.setFont(new Font("TimesRoman", Font.PLAIN, 20));
frame.getContentPane().add(commit); JButton another = new JButton("再来一局");
another.setBorder(BorderFactory.createRaisedSoftBevelBorder()); // 设置凸出的效果
another.setBounds(610, 500, 120, 30);
another.setBackground(c2);
another.setFont(new Font("TimesRoman", Font.PLAIN, 20));
frame.getContentPane().add(another); String hintInform = new String();
hintInform = "游戏规则:<br>玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足"
+ "每一行、每一列、每一个颜色不同的(3*3)的小九宫格中分别填入1~9之间的数字,均不能重复。";
JLabel labelRule = new JLabel("<html>" + hintInform + "</html>");
labelRule.setBounds(610, 60, 220, 240);
labelRule.setFont(new Font("TimesRoman", Font.PLAIN, 20));
frame.getContentPane().add(labelRule); JLabel labelLevel = new JLabel();
labelLevel.setText("选择难易程度:");
labelLevel.setBounds(610, 327, 180, 30);
labelLevel.setFont(new Font("TimesRoman", Font.PLAIN, 20));
frame.getContentPane().add(labelLevel); JComboBox comboBox = new JComboBox();
comboBox.setFont(new Font("TimesRoman", Font.PLAIN, 20));
comboBox.addItem("难易适中");
comboBox.addItem("高手过招");
comboBox.addItem("新手上路"); comboBox.setSelectedIndex(level);
comboBox.setBounds(610, 370, 200,30 );
frame.getContentPane().add(comboBox); /**
* 添加下拉框监听事件
*/
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
int choice = comboBox.getSelectedIndex();;
if (level != choice) {
level = choice;
main(null);
}
}
}); /**
* 添加按钮commit监听事件
*/
commit.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
int errorCount = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (!(chessBoard[i][j].getText().equals(Integer.toString(cellsAnswer[i][j])))) {
// 如果chessBoard内的文本与答案不相同
chessBoard[i][j].setForeground(Color.red);
chessBoard[i][j].setText(Integer.toString(cellsAnswer[i][j]));
errorCount++;
}
}
}
if (errorCount == 0) {
// 全部填写正确,弹出very good对话框
String successInfo = new String();
successInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "太厉害咯,送你一颗小心心!"
+ "</font></html>";
ImageIcon iconSucc = new ImageIcon("小心心.jpg");
JOptionPane.showMessageDialog(null, successInfo, "恭喜闯关成功!", JOptionPane.INFORMATION_MESSAGE,
iconSucc);
} else {
String failureInfo = new String();
failureInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "很遗憾,你填错了" + errorCount
+ "个格子!" + "<br>红色字体的格子显示的是正确答案哦!" + "<br>要不再来一局?!" + "</font></html>";
ImageIcon iconFail = new ImageIcon("哭泣的小熊猫.jpg");
JOptionPane.showMessageDialog(null, failureInfo, "挑战失败", JOptionPane.INFORMATION_MESSAGE,
iconFail);
}
}
}); /**
* 添加another再来一局的监听事件
*/
another.addActionListener(new ActionListener() { @Override
public void actionPerformed(ActionEvent e) {
main(null);
}
});
}
}
数独带挖空的棋盘生成代码如下:
/**
* 用来设置棋盘中的空白格子 要求:棋盘上总空格数大于30,小于60,每3*3小棋盘中挖空不少于2个
* 实现:为了配合GUI界面的生成,将游戏等级设置为level,
* level的值0表示难度适中,挖空27~36个格子,1表示较难,挖空36~54个格子,2表示简单,挖空18个格子
* 本类中直接生成的棋局难度为1,挖空36~54个格子
*/
private void setBlank(int level) {
// int blankSum = 0; //用来计算总的挖空数
int temp = 0; // temp得到每个3*3格子需要挖空的数量 for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (level == 0) { // level表示游戏难度,0表示难度适中
temp = (int) (Math.random() * 10) % 2 + 3; // temp得到每个3*3格子需要挖空的数量3~4个
} else if (level == 1) { // level为1时表示较难
temp = (int) (Math.random() * 10) % 3 + 4; // temp得到每个3*3格子需要挖空的数量4~6个
} else { // level为2时设置为新手上路
temp = 2; // temp得到每个3*3格子需要挖空的数量2个
}
// blankSum += temp;
while (temp > 0) {
int blankRandom = (int) (Math.random() * 10) % 9;
// 将3*3九宫格从左到右,从上到下当做标号为0~8的格子,取随机数表示当前3*3的格子内需要挖空的格子位置
// 以下三句计算要挖空的格子在整个棋盘上的位置
int rowTemp = blankRandom / 3;
int row = rowTemp + i * 3;
int col = blankRandom - 3 * rowTemp + j * 3;
if (chess[row][col] != 0) {
chess[row][col] = 0;
} else {
continue;
}
temp--;
}
}
}
// System.out.println("blankSum = " + blankSum);
// show(chess);
}
GUI界面截图如下:
功能介绍:图一游戏开始默认为难度适中,玩家可以在“下拉框”选择游戏难度,空着的格子可以填入数字,玩家填写完成之后点击“提交答案”按钮,如果全部正确会出现图二的提示框,如果有错误会出现图三所示的提示框,玩家填错了的位置会在棋局内以红色字体显示,此格子内显示的是正确答案。点击“再玩一局”按钮可以重新开始游戏。
(下图为图一)
(下图为图二)
(下图为图三)
作业要求的生成数独棋盘后将其写入文件“sudotiku.txt”中,结果如下:(两个程序的完整代码已上传至coding,地址:https://coding.net/u/dhlg_201810812008/p/sudotiku/git/tree/master/firstGui/src/firstGui)
请输入要生成的数独的个数:(1~1000000之间)3
9 8 0 0 4 3 0 0 2
0 3 4 0 0 7 6 8 0
5 0 0 0 8 9 0 3 0
0 0 3 4 0 0 0 0 0
4 5 0 7 0 8 0 0 3
0 0 0 3 0 2 4 6 5
0 0 2 5 7 0 0 4 8
0 0 9 8 3 0 0 2 0
8 0 5 9 0 0 3 7 0
0 3 9 7 0 0 0 1 0
1 0 0 3 0 8 6 0 9
0 0 0 1 0 9 0 0 8
0 0 3 4 0 0 0 9 0
0 5 0 8 0 7 1 0 3
7 0 0 0 1 3 0 4 0
3 4 0 6 0 1 0 0 0
0 0 1 0 0 2 3 0 4
0 8 2 0 3 0 7 6 1
0 2 0 9 0 0 0 4 5
1 0 0 2 0 6 7 0 9
0 8 9 0 0 0 0 3 0
0 1 0 4 0 0 0 9 8
0 0 7 6 0 0 3 0 0
0 9 0 3 1 0 4 0 0
0 0 0 7 9 0 0 0 0
8 6 1 0 0 4 9 0 0
9 0 4 8 0 3 5 0 1
程序运行的正确性以及性能分析:GUI游戏界面运行正常,填入答案后玩家可以得到正确性反馈,也可以根据需要调整游戏难度,性能较好。
本次学习总结: 由于之前没有做过GUI界面,个人感觉这次的作业对我的挑战很大,总共用了3~4天的时间。但是通过本次实践项目也学习到了很多Java的知识点,以下做个简单的总结。
1、java中两个二维数组answer和chess,要将answer的值赋给chess,如果使用chess = answer结果是引用传递,使用arraycopy方式只能实现一维数组的赋值。要给二维数组赋值必须要将其当做数组的数组,一个数组一个数组地赋值。代码如下:(CSDN上关于数组的赋值问题博客 https://blog.csdn.net/u010000515/article/details/72845085)
for (int i = 0; i < answer.length; i++) {
System.arraycopy(answer[i], 0, chess[i], 0, answer.length);
}
2、关于GUI的一些知识点罗列如下:
frame.setResizable(false); //设置窗口是否可变大小
frame.getContentPane().setLayout(null); //要设置Jpanel的位置与大小,要先关闭frame的布局管理器
chessBoard[i][j].setFocusable(false); // 设置是否可获得焦点
JLabel labelRule = new JLabel("<html>" + hintInform + "</html>"); //JLabel中要实现超出宽度自动换行可以使用html来实现,还可以加<br>实现换行
/** 以下代码添加某个按钮的监听事件*/
comboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
//添加监听事件
}
});
3、学习中遇到的问题可以说是非常多了,对GUI界面的控件和方法不熟悉等等,主要是查阅API文档和网上百度得到解答,觉得对于我比较难的应该是对控件方法的调用和监听事件,以后还需多多学习。
基于第二次数独游戏,添加GUI界面的更多相关文章
- 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)
本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...
- [置顶] 使用红孩儿工具箱完成基于Cocos2d-x的简单游戏动画界面
[Cocos2d-x相关教程来源于红孩儿的游戏编程之路CSDN博客地址:http://blog.csdn.net/honghaier 红孩儿Cocos2d-X学习园地QQ3群:205100149,47 ...
- iOS开发 Swift开发数独游戏(四) 游戏界面的界面与逻辑
一.游戏界面涉及到的功能点 1)数独格子的建模 (1)绘制数独格子要考虑到标记功能 所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作S ...
- 基于深度学习的车辆检测系统(MATLAB代码,含GUI界面)
摘要:当前深度学习在目标检测领域的影响日益显著,本文主要基于深度学习的目标检测算法实现车辆检测,为大家介绍如何利用\(\color{#4285f4}{M}\color{#ea4335}{A}\colo ...
- iOS开发 Swift开发数独游戏(三) 选关界面
一.选关界面涉及到的功能点 1)需要UITableView以及相应数据代理.协议的实现 2)读取plist文件并转化成模型 3)在单元格点击后进入数独游戏,涉及到把数据经segue在UIViewCon ...
- 150+行Python代码实现带界面的数独游戏
150行代码实现图形化数独游戏 Github地址,欢迎各位大佬们fork.star啥的,感谢: 今天闲着没事干,以前做过html+js版的数独,这次做个python版本的,界面由pygame完成,数独 ...
- 使用Xamarin开发移动应用示例——数独游戏(七)添加新游戏
项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu .代码随项目进度更新. 现在我们增加添加新游戏的功能,创建一个页面,编辑初始局面,并保存到数据库. ...
- matlab GUI界面编程总结
去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起吧. 创建Matlab ...
- Matlab GUI界面
做SVD的时候,看学姐的demo,用到了matlab的GUI,感兴趣就自己学了一下: 从简单的例子说起吧. 创建Matlab GUI界面通常有两种方式: 1,使用 .m 文件直接动态添加控件 ...
随机推荐
- 5、numpy——切片和索引
1.一维数组 1.1 一维数组很简单,基本和列表一致.ndarray 数组可以基于 0 - n 的下标进行索引. 切片对象可以通过内置的 slice 函数,并设置 start, stop 及 step ...
- JS高级 — 函数中的this指向问题
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- vue.js(09)--v-for中的key
v-for中key的使用注意事项 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- centos install vsftpd
1.安装 #安装Vsftpd服务相关部件 yum -y install vsftpd* #确认安装PAM服务相关部件, 开发包,其实不装也没有关系,主要的目的是确认PAM. yum -y instal ...
- JSONP面试
jQuery 的 JSONP的原理是动态创建一个 script 标签,利用src 发送请求,获取数据 回调函数的键名叫做 callback 跟ajax没有关系 JSONP:主要是利用 script标 ...
- rpmdeps - 生成 RPM 软件包依赖关系
SYNOPSIS rpmdeps {-P|--provides} {-R|--requires} FILE ... DESCRIPTION rpmdeps 根据 FILE 参数集合,生成软件包依赖关系 ...
- Strcpy,strcpy使用注意
一.char *strcpy(char *dest, const char *src) 参数 dest -- 指向用于存储复制内容的目标数组. src -- 要复制的字符串. 注意: 1.dest需要 ...
- Struts2基础-2 -实现Action接口创建Action控制器
1.新建一个web项目,目录结构如下,添加jar包到lib文件夹里,并把jar包add 到 buildpath里面 2.web.xml配置 struts2的过滤器类:StrutsPrepareAndE ...
- PHP curl_multi_close函数
curl_multi_close — 关闭一组cURL句柄 说明 void curl_multi_close ( resource $mh ) 关闭一组cURL句柄. 参数 mh 由 curl_mul ...
- angualr项目引入容联 七陌7mroo
最近项目要求在注册页面增加客服服务浮窗,各种查找资料准备采用7moor来实现.现记录一下实现过程,便于后期查看: 引入7moor浮窗有两种方式: 1.h5方式,这种情况一般是单独打开新页面即可: 直接 ...