高级软件工程第三次作业:基于第二次数独游戏,添加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界面的更多相关文章

  1. 【Visual C++】游戏开发五十六 浅墨DirectX教程二十三 打造游戏GUI界面(一)

    本系列文章由zhmxy555(毛星云)编写,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/16384009 作者:毛星云 ...

  2. [置顶] 使用红孩儿工具箱完成基于Cocos2d-x的简单游戏动画界面

    [Cocos2d-x相关教程来源于红孩儿的游戏编程之路CSDN博客地址:http://blog.csdn.net/honghaier 红孩儿Cocos2d-X学习园地QQ3群:205100149,47 ...

  3. iOS开发 Swift开发数独游戏(四) 游戏界面的界面与逻辑

    一.游戏界面涉及到的功能点 1)数独格子的建模 (1)绘制数独格子要考虑到标记功能 所以要在每个格子内预先塞入9个标记数字,仅数独格子算下来就有9*9*9=729个格子且存在大量嵌套(这导致我在操作S ...

  4. 基于深度学习的车辆检测系统(MATLAB代码,含GUI界面)

    摘要:当前深度学习在目标检测领域的影响日益显著,本文主要基于深度学习的目标检测算法实现车辆检测,为大家介绍如何利用\(\color{#4285f4}{M}\color{#ea4335}{A}\colo ...

  5. iOS开发 Swift开发数独游戏(三) 选关界面

    一.选关界面涉及到的功能点 1)需要UITableView以及相应数据代理.协议的实现 2)读取plist文件并转化成模型 3)在单元格点击后进入数独游戏,涉及到把数据经segue在UIViewCon ...

  6. 150+行Python代码实现带界面的数独游戏

    150行代码实现图形化数独游戏 Github地址,欢迎各位大佬们fork.star啥的,感谢: 今天闲着没事干,以前做过html+js版的数独,这次做个python版本的,界面由pygame完成,数独 ...

  7. 使用Xamarin开发移动应用示例——数独游戏(七)添加新游戏

    项目代码可以从Github下载:https://github.com/zhenl/ZL.Shudu .代码随项目进度更新. 现在我们增加添加新游戏的功能,创建一个页面,编辑初始局面,并保存到数据库. ...

  8. matlab GUI界面编程总结

    去年做了一些关于Matlab GUI的程序,现在又要做相关的东西,回想起来,当时很多经验没有记录下来,现在回顾起来始终觉得不爽,所以从现在开始,一定要勤写记录. 从简单的例子说起吧. 创建Matlab ...

  9. Matlab GUI界面

    做SVD的时候,看学姐的demo,用到了matlab的GUI,感兴趣就自己学了一下: 从简单的例子说起吧. 创建Matlab GUI界面通常有两种方式: 1,使用 .m 文件直接动态添加控件     ...

随机推荐

  1. 关于Echarts的使用和遇到的问题

    对于插件工具,感觉按着官方的教程,便可以使用,但是看这个Echarts有点晕乎乎的,还是不能快速的学习啊. 一.在webpack中使用ECharts //通过 npm 获取 echartsnpm in ...

  2. k3 cloud成本调整单引入单据后,再做出库成本核算。成本调整单列表已审核的单据消失,非已审核的单据还在,这是出库成本核算设置参数的问题吗?

    存货核算时,会将“期末余额调整”类型的的调整单删除后,再重新产生:因此引入后不要再做出库核算,或者引入其它类型的单据.

  3. 基于mesos 安装 jenkins

    mesos master 机子上安装  jenkins git clone https://github.com/jenkinsci/mesos-plugin.git && cd me ...

  4. Vue 踩坑日志 - 有关路由传参的坑

    1.有关路由传参 vue中当通过params传过去的参数刷新页面以后会消失,所以可以用query传参.但此时又会出现另一个坑,刷新后数据仍在.但这是针对单个的某个变量的. 如果传入一个对象的话,刷新页 ...

  5. iOS crash log 解析

    iOS开发中,经常遇到App在开发及测试时不会有问题,但是装在别人的设备中会出现各种不定时的莫名的 crash,因为iOS设备会保存应用的大部分的 crash Log,所以可以通过 crash Log ...

  6. 六、SQL语句进行多条件查询,并解决参数为空的情况

    一.SQL语句进行多条件查询,并解决参数为空的情况 QueryEntity query; var whereSql = new StringBuilder("Where 1=1") ...

  7. Linux修改密码指令

    1.在选择系统菜单界面,按 "e" 进入编辑模式 2.在以字符串“Linux16”开头的行,将光标移动到该行的结尾,然后输入“init=/bin/bash”,按 "Ctr ...

  8. Mac OS 10.15系统入门教程 系统语言输入法详解

    对于一些Mac新手来说呢还不知道偏好设置到底是什么?有什么用处?其实Mac系统内的几乎所有的系统相关的设置都会在系统偏好设置内出现. 切换系统语⾔在语言与地区设置中拖拽左侧的语言条目就可以切换系统的语 ...

  9. boost phoenix

    In functional programming, functions are objects and can be processed like objects. With Boost.Phoen ...

  10. PHP 利用 curl 发送 post get del put patch 请求

    因为需要在 php 开发中对接其它接口需要用 php curl 去对接其它接口 我把他们封装成函数 希望能对大家有所帮助. 这里面是封装好的会自动把 data 进行转成 json 格式,同时解码成 p ...