zoukankan      html  css  js  c++  java
  • 基于第二次数独游戏,添加GUI界面

    高级软件工程第三次作业:基于第二次数独游戏,添加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轴上的起点 组件的长度 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             /**
    154              * 添加按钮commit监听事件
    155              */
    156             commit.addActionListener(new ActionListener() {
    157 
    158                 @Override
    159                 public void actionPerformed(ActionEvent e) {
    160                     int errorCount = 0;
    161                     for (int i = 0; i < 9; i++) {
    162                         for (int j = 0; j < 9; j++) {
    163                             if (!(chessBoard[i][j].getText().equals(Integer.toString(cellsAnswer[i][j])))) {
    164                                 // 如果chessBoard内的文本与答案不相同
    165                                 chessBoard[i][j].setForeground(Color.red);
    166                                 chessBoard[i][j].setText(Integer.toString(cellsAnswer[i][j]));
    167                                 errorCount++;
    168                             }
    169                         }
    170                     }
    171                     if (errorCount == 0) {
    172                         // 全部填写正确,弹出very good对话框
    173                         String successInfo = new String();
    174                         successInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "太厉害咯,送你一颗小心心!"
    175                                 + "</font></html>";
    176                         ImageIcon iconSucc = new ImageIcon("小心心.jpg");
    177                         JOptionPane.showMessageDialog(null, successInfo, "恭喜闯关成功!", JOptionPane.INFORMATION_MESSAGE,
    178                                 iconSucc);
    179                     } else {
    180                         String failureInfo = new String();
    181                         failureInfo = "<html><font face = " + "宋体 " + "size = " + "5" + ">" + "很遗憾,你填错了" + errorCount
    182                                 + "个格子!" + "<br>红色字体的格子显示的是正确答案哦!" + "<br>要不再来一局?!" + "</font></html>";
    183                         ImageIcon iconFail = new ImageIcon("哭泣的小熊猫.jpg");
    184                         JOptionPane.showMessageDialog(null, failureInfo, "挑战失败", JOptionPane.INFORMATION_MESSAGE,
    185                                 iconFail);
    186                     }
    187                 }
    188             });
    189 
    190             /**
    191              * 添加another再来一局的监听事件
    192              */
    193             another.addActionListener(new ActionListener() {
    194 
    195                 @Override
    196                 public void actionPerformed(ActionEvent e) {
    197                     main(null);
    198                 }
    199             });
    200     }
    201 }

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

     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文档和网上百度得到解答,觉得对于我比较难的应该是对控件方法的调用和监听事件,以后还需多多学习。

  • 相关阅读:
    Flutter -- iOS导航栏TabBar
    微信小程序布局
    Tomcat for Mac 搭建本地后台服务器 -- 探索Apache Tomcat
    masnory 动态高度
    iPhone 尺度 x xs sr xsmax
    Deepin 安装 tomcat
    Deepin 设置静态 ip
    md 文件 转 pdf
    mac 上关于截图的偏好设置
    MySQL笔记---DDL
  • 原文地址:https://www.cnblogs.com/dyls/p/9785532.html
Copyright © 2011-2022 走看看