高级软件工程第三次作业:基于第二次数独游戏,添加GUI界面。GUI界面代码如下:

  1. package firstGui;
  2.  
  3. import java.awt.*;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.ItemEvent;
  7. import java.awt.event.ItemListener;
  8.  
  9. import javax.swing.*;
  10.  
  11. import org.eclipse.swt.widgets.ExpandItem;
  12.  
  13. public class sudokuGui2 {
  14.  
  15. private JFrame frame;
  16. static int[][] cellsAnswer = new int[9][9];
  17. static int[][] cells = new int[9][9];
  18. static int level = 0; //表示游戏等级
  19.  
  20. public static void main(String[] args) {
  21. EventQueue.invokeLater(new Runnable() {
  22. public void run() {
  23. try {
  24. sudokuGui2 window = new sudokuGui2();
  25. window.frame.setVisible(true);
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. }
  30. });
  31. }
  32.  
  33. /**
  34. * 构造方法
  35. */
  36. public sudokuGui2() {
  37. initialize();
  38. }
  39.  
  40. /**
  41. * 初始化窗体
  42. */
  43. private void initialize() {
  44.  
  45. frame = new JFrame("数独游戏");
  46. // setBounds(x,y,width,height);
  47. // x:组件在容器X轴上的起点 y:组件在容器Y轴上的起点 width:组件的长度 height:组件的高度
  48. frame.setBounds(100, 100, 900, 680);
  49. frame.setResizable(false); //设置窗口是否可变大小
  50. frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  51. frame.getContentPane().setLayout(null); //要设置Jpanel的位置与大小,要先关闭frame的布局管理器
  52. JPanel panel = new JPanel();
  53. panel.setBounds(80, 60, 500, 500);
  54. frame.getContentPane().add(panel);
  55.  
  56. Color c1 = new Color(253, 237, 237);
  57. Color c2 = new Color(254, 254, 254);
  58.  
  59. JTextField[][] chessBoard = new JTextField[9][9];
  60. sudokuV2_modify shudu = new sudokuV2_modify(level);
  61. cellsAnswer = shudu.getAnswer(); // 从sudokuV2_modify获取数独的答案
  62. cells = shudu.getChess();
  63.  
  64. // shudu.show(cellsAnswer);
  65. // System.out.println();
  66. // shudu.show(cells);
  67.  
  68. /**
  69. * 设置棋盘的初始状态
  70. */
  71. panel.setLayout(new GridLayout(9, 9));
  72. for (int i = 0; i < 9; i++) {
  73. for (int j = 0; j < 9; j++) {
  74. // 设置JTextField的内容
  75. chessBoard[i][j] = new JTextField();
  76. chessBoard[i][j].setFont(new Font("TimesRoman", Font.PLAIN, 26));
  77. chessBoard[i][j].setHorizontalAlignment(JTextField.CENTER);
  78. if (cells[i][j] == 0) {
  79. chessBoard[i][j].setForeground(Color.gray);
  80. } else {
  81. chessBoard[i][j].setText(Integer.toString(cells[i][j]));
  82. chessBoard[i][j].setFocusable(false); // 设置是否可获得焦点
  83. // chessBoard[i][j].setEnabled(false); //设置是否处于激活状态
  84. }
  85.  
  86. /** 设置3*3九宫格的背景颜色 */
  87. if ((i / 3 == 0 && j / 3 == 0) || (i / 3 == 1 && j / 3 == 1) || (i / 3 == 2 && j / 3 == 2)
  88. || (i / 3 == 0 && j / 3 == 2) || (i / 3 == 2 && j / 3 == 0)) {
  89. chessBoard[i][j].setBackground(c1);
  90. } else {
  91. chessBoard[i][j].setBackground(c2);
  92. }
  93.  
  94. chessBoard[i][j].setVisible(true);
  95. panel.add(chessBoard[i][j]);
  96. panel.setVisible(true);
  97. }
  98. }
  99.  
  100. JButton commit = new JButton("提交答案");
  101. commit.setBounds(610, 440, 120, 30);
  102. commit.setBorder(BorderFactory.createRaisedBevelBorder());
  103. commit.setBackground(c1);
  104. commit.setFont(new Font("TimesRoman", Font.PLAIN, 20));
  105. frame.getContentPane().add(commit);
  106.  
  107. JButton another = new JButton("再来一局");
  108. another.setBorder(BorderFactory.createRaisedSoftBevelBorder()); // 设置凸出的效果
  109. another.setBounds(610, 500, 120, 30);
  110. another.setBackground(c2);
  111. another.setFont(new Font("TimesRoman", Font.PLAIN, 20));
  112. frame.getContentPane().add(another);
  113.  
  114. String hintInform = new String();
  115. hintInform = "游戏规则:<br>玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足"
  116. + "每一行、每一列、每一个颜色不同的(3*3)的小九宫格中分别填入1~9之间的数字,均不能重复。";
  117. JLabel labelRule = new JLabel("<html>" + hintInform + "</html>");
  118. labelRule.setBounds(610, 60, 220, 240);
  119. labelRule.setFont(new Font("TimesRoman", Font.PLAIN, 20));
  120. frame.getContentPane().add(labelRule);
  121.  
  122. JLabel labelLevel = new JLabel();
  123. labelLevel.setText("选择难易程度:");
  124. labelLevel.setBounds(610, 327, 180, 30);
  125. labelLevel.setFont(new Font("TimesRoman", Font.PLAIN, 20));
  126. frame.getContentPane().add(labelLevel);
  127.  
  128. JComboBox comboBox = new JComboBox();
  129. comboBox.setFont(new Font("TimesRoman", Font.PLAIN, 20));
  130. comboBox.addItem("难易适中");
  131. comboBox.addItem("高手过招");
  132. comboBox.addItem("新手上路");
  133.  
  134. comboBox.setSelectedIndex(level);
  135. comboBox.setBounds(610, 370, 200,30 );
  136. frame.getContentPane().add(comboBox);
  137.  
  138. /**
  139. * 添加下拉框监听事件
  140. */
  141. comboBox.addItemListener(new ItemListener() {
  142. @Override
  143. public void itemStateChanged(ItemEvent e) {
  144. int choice = comboBox.getSelectedIndex();;
  145. if (level != choice) {
  146. level = choice;
  147. main(null);
  148. }
  149. }
  150. });
  151.  
  152. /**
  153. * 添加按钮commit监听事件
  154. */
  155. commit.addActionListener(new ActionListener() {
  156.  
  157. @Override
  158. public void actionPerformed(ActionEvent e) {
  159. int errorCount = 0;
  160. for (int i = 0; i < 9; i++) {
  161. for (int j = 0; j < 9; j++) {
  162. if (!(chessBoard[i][j].getText().equals(Integer.toString(cellsAnswer[i][j])))) {
  163. // 如果chessBoard内的文本与答案不相同
  164. chessBoard[i][j].setForeground(Color.red);
  165. chessBoard[i][j].setText(Integer.toString(cellsAnswer[i][j]));
  166. errorCount++;
  167. }
  168. }
  169. }
  170. if (errorCount == 0) {
  171. // 全部填写正确,弹出very good对话框
  172. String successInfo = new String();
  173. successInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "太厉害咯,送你一颗小心心!"
  174. + "</font></html>";
  175. ImageIcon iconSucc = new ImageIcon("小心心.jpg");
  176. JOptionPane.showMessageDialog(null, successInfo, "恭喜闯关成功!", JOptionPane.INFORMATION_MESSAGE,
  177. iconSucc);
  178. } else {
  179. String failureInfo = new String();
  180. failureInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "很遗憾,你填错了" + errorCount
  181. + "个格子!" + "<br>红色字体的格子显示的是正确答案哦!" + "<br>要不再来一局?!" + "</font></html>";
  182. ImageIcon iconFail = new ImageIcon("哭泣的小熊猫.jpg");
  183. JOptionPane.showMessageDialog(null, failureInfo, "挑战失败", JOptionPane.INFORMATION_MESSAGE,
  184. iconFail);
  185. }
  186. }
  187. });
  188.  
  189. /**
  190. * 添加another再来一局的监听事件
  191. */
  192. another.addActionListener(new ActionListener() {
  193.  
  194. @Override
  195. public void actionPerformed(ActionEvent e) {
  196. main(null);
  197. }
  198. });
  199. }
  200. }

数独带挖空的棋盘生成代码如下:

  1. /**
  2. * 用来设置棋盘中的空白格子 要求:棋盘上总空格数大于30,小于60,每3*3小棋盘中挖空不少于2个
  3. * 实现:为了配合GUI界面的生成,将游戏等级设置为level,
  4. * level的值0表示难度适中,挖空27~36个格子,1表示较难,挖空36~54个格子,2表示简单,挖空18个格子
  5. * 本类中直接生成的棋局难度为1,挖空36~54个格子
  6. */
  7. private void setBlank(int level) {
  8. // int blankSum = 0; //用来计算总的挖空数
  9. int temp = 0; // temp得到每个3*3格子需要挖空的数量
  10.  
  11. for (int i = 0; i < 3; i++) {
  12. for (int j = 0; j < 3; j++) {
  13. if (level == 0) { // level表示游戏难度,0表示难度适中
  14. temp = (int) (Math.random() * 10) % 2 + 3; // temp得到每个3*3格子需要挖空的数量3~4个
  15. } else if (level == 1) { // level为1时表示较难
  16. temp = (int) (Math.random() * 10) % 3 + 4; // temp得到每个3*3格子需要挖空的数量4~6个
  17. } else { // level为2时设置为新手上路
  18. temp = 2; // temp得到每个3*3格子需要挖空的数量2个
  19. }
  20. // blankSum += temp;
  21. while (temp > 0) {
  22. int blankRandom = (int) (Math.random() * 10) % 9;
  23. // 将3*3九宫格从左到右,从上到下当做标号为0~8的格子,取随机数表示当前3*3的格子内需要挖空的格子位置
  24. // 以下三句计算要挖空的格子在整个棋盘上的位置
  25. int rowTemp = blankRandom / 3;
  26. int row = rowTemp + i * 3;
  27. int col = blankRandom - 3 * rowTemp + j * 3;
  28. if (chess[row][col] != 0) {
  29. chess[row][col] = 0;
  30. } else {
  31. continue;
  32. }
  33. temp--;
  34. }
  35. }
  36. }
  37. // System.out.println("blankSum = " + blankSum);
  38. // show(chess);
  39. }

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. 使用redis来存储session,不同框架对session的命名规则是不一样的

    今天做了一个测试,在同一个云服务器上,搭建了两个server,其中一个是用laravel框架写的,另外一个使用原生php开发的,为了提高访问的速度,使用云服务器中的redis来存储session数据, ...

  2. 04 volatile关键字实现原理

    volatile关键字实现原理 1.volatile关键字的语义分析 作用:让其他线程能够马上感知到某个线程多某个变量的修改 保证可见性 对共享变量的修改,其他线程能够马上感知到 保证有序性 在重排序 ...

  3. go web编程——session管理机制设计与实现

    原生Go语言没有实现session管理机制,所以如果使用原生Go语言进行web编程,我们需要自己进行session管理机制的设计与实现,本文将就此进行详细介绍,并实现一个简单的session管理机制. ...

  4. shell变量的声明和使用

  5. 消息队列之AciveMQ

    activemq安全设置 设置admin的用户名和密码  

  6. STM32F103系列命名规则

    对于STM32F103xxyy系列:第一个x代表引脚数:T-36pin,C-48pin,R-64pin,V-100pin,Z-144pin:第二个x代表Flash容量:6-32K,8-64K,B-12 ...

  7. SpringBoot---提供的自动配置

    1.自动配置的ViewResolver 1.1.ContentNegotiatingViewResolver 1.2.BeanNameViewResolver 1.3.InternalResource ...

  8. vue 项目的运行与 打包

    1.vue init webpack 2.npm install axios 3.npm run dev  运行项目 4.npm run build 打包项目 会生成一个dist 文件夹,我们只需要把 ...

  9. gensim word2vec |来自渣渣硕的学习笔记

    最近写论文跑模型,要用到word2vec,但是发现自己怎么也看不懂网上的帖子,还是自己笨吧,所以就有了我的第一篇博客!!!  关于word2vec工具打算写一个系列的,当然今天这篇文章只打算写: 如何 ...

  10. 解决如何通过循环来使用数据库的值设置jsp的select标签的option值

    Select 处的代码: <select name="position"> <span style="white-space:pre"> ...