你的位置:首页 > Java教程

[Java教程]【代码笔记】Java连连看项目的实现——JTable 、TableModel的使用


  1. 博客有时间就写写,所以一篇可能会拆成很多篇,写完后计划再合在一起。
  2. 首先肯定是要实现连连看的界面。
    1. 先准备连连看要的图片。、
    2. “LianLianKan”就是项目名称。
    3. 当然,如果小白看我的博客想学到什么,我会说还是放弃,因为文字描述会忽视很多细节,而细节决定bug……
    4. 所以,包括以前的和以后的,博文都会是给自己看看或者内行触类旁通的,也就是——笔记。
    5. 我也是今天才明白博文的真正意义吧,所以以后的博文风格会大改……尽量会用自己语言风格来描述以便自己能看懂。
  3. 废话少说,现在的第2步:
    1. 创建数组,一个持久化存储的容器:存储连连看的图片 迷宫寻路
    2. 2.有图像在数组看得到,先秀一下看看,免得一开始代码就错了,后面还写个毛。
    3. 到这一步,主函数基本没什么变化。TableFrame.java
       1 package com.edp.impl; 2  3  4 import java.awt.FlowLayout; 5  6 import javax.swing.JFrame; 7 import javax.swing.JTable; 8  9 /**10  * 11  * @author Administrator12  *13 */14 @SuppressWarnings("serial")15 public class TableFrame extends JFrame{16   public static void main(String[] args) {17     new TableFrame().initFrame();18   }19 20   private void initFrame() {21     this.setSize(800,600);22     this.setDefaultCloseOperation(3);23     this.setLayout(new FlowLayout());24     //设置窗体不能改变大小25     this.setResizable(false);26     this.setLocationRelativeTo(null);27     28     MyTableModel mtm = new MyTableModel(); 29     JTable table = new JTable(mtm);30     this.add(table);31     this.setVisible(true);32     33   }34 }

       

    4. 说明在代码里面写清楚了 。
       1 package com.edp.impl; 2  3 import java.util.Random; 4  5 import javax.swing.event.TableModelListener; 6 import javax.swing.table.TableModel; 7  8 public class MyTableModel implements TableModel { 9   //1.创建数组,一个持久化存储的容器:存储连连看的图片 迷宫寻路10   private String[][] saveDB = new String[13][13];11   //2.有图像在数组看得到12   //2_2在存的时候想到图片最好随机13   private Random ran = new Random();//创建随机对象14   //2_1 把图片存到数组15   public MyTableModel() {16     int value;17     for(int i = 0;i<saveDB.length;i++){18       for (int j = 0; j < saveDB[i].length; j++) {19         value = ran.nextInt(13)+1;20         saveDB[i][j] = "image/lianliankanimage/"+value+".jpg";21       }22     }23   }24   25   //获取列类型26   public Class<?> getColumnClass(int columnIndex) {27     return String.class;28   }29   //获取总行数30   public int getRowCount() {31     return saveDB.length;32   }33   //获取总列数34   public int getColumnCount() {35     return saveDB[0].length;36   }37   //获取表格列名38   public String getColumnName(int columnIndex) {39     //连连看游戏没必要出现表格列名呀,反正不需要40     //实现列名可以通过switch语句,最适合实现。然后在TableFrame类里面实现41     //不过想要实现得这样(用到JScrollPane):42     //  JTable table = new JTable(mtm);43     //  //把JTable对象加载到JScrollPane44     //   JScrollPane jsp = new JScrollPane(table);45     //  this.add(jsp);46     //JScrollPane到底是个什么玩意,请自己去查java API说明书。47     return null;48   }49   //设置单元格数据50   public void setValueAt(Object aValue, int rowIndex, int columnIndex) {51   }52   //获得单元格数据53   public Object getValueAt(int rowIndex, int columnIndex) {54     return 0;55   }56   //单元格是否编辑57   public boolean isCellEditable(int rowIndex, int columnIndex) {58     //连连看游戏肯定不需要对单元格进行修改或删除,游戏逻辑自会处理相关格子内的东西。59     return false;60   }61   public void removeTableModelListener(TableModelListener l) {}62   public void addTableModelListener(TableModelListener l) {}63 }

       

    5. 运行结果是这样子的
    6. 然后开始插入图片看看。
    7. TableFrame.java
       1 package com.edp.impl; 2  3  4 import java.awt.FlowLayout; 5  6 import javax.swing.JFrame; 7 import javax.swing.JTable; 8 import javax.swing.table.TableColumnModel; 9 10 /**11  * 12  * @author Administrator13  *14 */15 @SuppressWarnings("serial")16 public class TableFrame extends JFrame{17   public static void main(String[] args) {18     new TableFrame().initFrame();19   }20 21   private void initFrame() {22     this.setSize(800,600);23     this.setDefaultCloseOperation(3);24     this.setLayout(new FlowLayout());25     //设置窗体不能改变大小26     this.setResizable(false);27     this.setLocationRelativeTo(null);28     29     MyTableModel mtm = new MyTableModel(); 30     JTable table = new JTable(mtm);31     this.add(table);32     //设置显示样式33     //列宽34     table.setRowHeight(35);35     //获取列模型36     TableColumnModel columnModel = table.getColumnModel();37     for (int i = 0; i < columnModel.getColumnCount(); i++) {38       columnModel.getColumn(i).setPreferredWidth(35);39     }40     //设置行列都不能被选中41     table.setRowSelectionAllowed(false);42     table.setColumnSelectionAllowed(false);43     this.setVisible(true);44     45   }46 }

       

    8. MyTableModel.java
       1 package com.edp.impl; 2  3 import java.util.Random; 4  5 import javax.swing.ImageIcon; 6 import javax.swing.event.TableModelListener; 7 import javax.swing.table.TableModel; 8  9 public class MyTableModel implements TableModel {10   //1.创建数组,一个持久化存储的容器:存储连连看的图片 迷宫寻路11   private String[][] saveDB = new String[13][13];12   //2.有图像在数组看得到13   //2_2在存的时候想到图片最好随机14   private Random ran = new Random();//创建随机对象15   //2_1 把图片存到数组16   public MyTableModel() {17     int value;18     for(int i = 0;i<saveDB.length;i++){19       for (int j = 0; j < saveDB[i].length; j++) {20         value = ran.nextInt(13)+1;21         saveDB[i][j] = "image/"+value+".jpg";22       }23     }24   }25   26   //获取列类型27   public Class<?> getColumnClass(int columnIndex) {28     return javax.swing.ImageIcon.class;29   }30   //获取总行数31   public int getRowCount() {32     return saveDB.length;33   }34   //获取总列数35   public int getColumnCount() {36     //这里考虑一个bug:如果连列数都没有,这行代码就会报出异常37     if(saveDB.length>0){38       return saveDB[0].length;39     }40     return 0;41   }42   //获取表格列名43   public String getColumnName(int columnIndex) {44     //连连看游戏没必要出现表格列名呀,反正不需要45     //实现列名可以通过switch语句,最适合实现。然后在TableFrame类里面实现46     //不过想要实现得这样(用到JScrollPane):47     //  JTable table = new JTable(mtm);48     //  //把JTable对象加载到JScrollPane49     //   JScrollPane jsp = new JScrollPane(table);50     //  this.add(jsp);51     //JScrollPane到底是个什么玩意,请自己去查java API说明书。52     return null;53   }54   //设置单元格数据55   public void setValueAt(Object aValue, int rowIndex, int columnIndex) {56     saveDB[rowIndex][columnIndex] = (String)aValue;57   }58   //获得单元格数据59   public Object getValueAt(int rowIndex, int columnIndex) {60     //返回图片61     ImageIcon icon = new ImageIcon(saveDB[rowIndex][columnIndex]);62     return icon;63 64   }65   //单元格是否编辑66   public boolean isCellEditable(int rowIndex, int columnIndex) {67     //连连看游戏肯定不需要对单元格进行修改或删除,游戏逻辑自会处理相关格子内的东西。68     return false;69   }70   public void removeTableModelListener(TableModelListener e) {}71   public void addTableModelListener(TableModelListener e) {}72 }

       

    9. 运行后,什么都出来了。
    10. 接下来是实现连连看游戏的消除。
    11. 消除肯定要用鼠标点呀点的。而实现鼠标操作,肯定是要监控。
    12. 监控插哪呢,肯定要是面板创建完,就监控。
    13. 回顾一下处理连连看消除逻辑(算法实现)

      1. 相同图片能够消除

      2. 在同一行或者同一列无障碍物可消除

      3. 一个拐点可消除

      4. 两个拐点可消除

    14. TableFrame.java
       1 package com.edp.impl; 2  3  4 import java.awt.FlowLayout; 5  6 import javax.swing.JFrame; 7 import javax.swing.JTable; 8 import javax.swing.table.TableColumnModel; 9 10 /**11  * 12  * @author Administrator13  *14 */15 @SuppressWarnings("serial")16 public class TableFrame extends JFrame{17   public static void main(String[] args) {18     new TableFrame().initFrame();19   }20 21   private void initFrame() {22     this.setSize(800,600);23     this.setDefaultCloseOperation(3);24     this.setLayout(new FlowLayout());25     //设置窗体不能改变大小26     this.setResizable(false);27     this.setLocationRelativeTo(null);28     29     MyTableModel mtm = new MyTableModel(); 30     JTable table = new JTable(mtm);31     this.add(table);32     //设置显示样式33     //列宽34     table.setRowHeight(35);35     //获取列模型36     TableColumnModel columnModel = table.getColumnModel();37     for (int i = 0; i < columnModel.getColumnCount(); i++) {38       columnModel.getColumn(i).setPreferredWidth(35);39     }40     //设置行列都不能被选中41     table.setRowSelectionAllowed(false);42     table.setColumnSelectionAllowed(false);43     this.setVisible(true);44     45     //添加监听器46     LLKMouseListener llkListener = new LLKMouseListener(mtm);47     table.addMouseListener(llkListener);48   }49 }

       

    15. MyTableModel.java
       1 package com.edp.impl; 2  3 import java.util.Random; 4  5 import javax.swing.ImageIcon; 6 import javax.swing.event.TableModelListener; 7 import javax.swing.table.TableModel; 8  9 public class MyTableModel implements TableModel {10   //1.创建数组,一个持久化存储的容器:存储连连看的图片 迷宫寻路11   private String[][] saveDB = new String[13][13];12   //2.有图像在数组看得到13   //2_2在存的时候想到图片最好随机14   private Random ran = new Random();//创建随机对象15   //2_1 把图片存到数组16   //3.消除肯定要用鼠标点呀点的。而实现鼠标操作,肯定是要监控。17   public MyTableModel() {18     int value;19     for(int i = 0;i<saveDB.length;i++){20       for (int j = 0; j < saveDB[i].length; j++) {21         value = ran.nextInt(13)+1;22         saveDB[i][j] = "image/"+value+".jpg";23       }24     }25   }26   27   //获取列类型28   public Class<?> getColumnClass(int columnIndex) {29     return javax.swing.ImageIcon.class;30   }31   //获取总行数32   public int getRowCount() {33     return saveDB.length;34   }35   //获取总列数36   public int getColumnCount() {37     //这里考虑一个bug:如果连列数都没有,这行代码就会报出异常38     if(saveDB.length>0){39       return saveDB[0].length;40     }41     return 0;42   }43   //获取表格列名44   public String getColumnName(int columnIndex) {45     //连连看游戏没必要出现表格列名呀,反正不需要46     //实现列名可以通过switch语句,最适合实现。然后在TableFrame类里面实现47     //不过想要实现得这样(用到JScrollPane):48     //  JTable table = new JTable(mtm);49     //  //把JTable对象加载到JScrollPane50     //   JScrollPane jsp = new JScrollPane(table);51     //  this.add(jsp);52     //JScrollPane到底是个什么玩意,请自己去查java API说明书。53     return null;54   }55   //设置单元格数据56   public void setValueAt(Object aValue, int rowIndex, int columnIndex) {57     saveDB[rowIndex][columnIndex] = (String)aValue;58   }59   //获得单元格数据60   public Object getValueAt(int rowIndex, int columnIndex) {61     //返回图片62     ImageIcon icon = new ImageIcon(saveDB[rowIndex][columnIndex]);63     return icon;64 65   }66   //单元格是否编辑67   public boolean isCellEditable(int rowIndex, int columnIndex) {68     //连连看游戏肯定不需要对单元格进行修改或删除,游戏逻辑自会处理相关格子内的东西。69     return false;70   }71   public void removeTableModelListener(TableModelListener e) {}72   public void addTableModelListener(TableModelListener e) {}73 74   public String[][] getSaveDB() {75     return saveDB;76   }77 }

      这一部分和之前没有多大变动,加了一个数组输入输出存储,eclipse自动报错加上去的。(74-76行)

    16. LLKMouseListener.java
       1 package com.edp.impl; 2  3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5  6 import javax.swing.JTable; 7  8 public class LLKMouseListener extends MouseAdapter{ 9   /**10   1.相同图片能够消除11   2.在同一行或者同一列无障碍物可消除12   3.一个拐点可消除13   4.两个拐点可消除14   */15   public MyTableModel mtm;16   17   //1_4.发现消除的是一个,点一个就消掉一个18   //所以需要做下关联, 控制第一次还是第二次点击的操作19   public boolean flag = true;20   public int row1, column1, row2, column2;21   //3.鼠标监控22   public LLKMouseListener(MyTableModel mtm) {23     this.mtm = mtm;24   }25   26   public void mousePressed(MouseEvent e) {27     //1.相同图片能够消除28     // 1_1.需要知道自己点击的是表格哪个位置29     // 1_2.得到被选中行被选中列30     JTable table = (JTable) e.getSource();31     32     // 1_3.把指定位置的图片消除:去除路径33     String[][] saveDB = mtm.getSaveDB();34     35     if(flag){36       row1 = table.getSelectedRow();37       column1 = table.getSelectedColumn();38       flag = false;39     }else{40       row2 = table.getSelectedRow();41       column2 = table.getSelectedColumn();42       saveDB[row1][column1] = "";43       saveDB[row2][column2] = "";44       flag = true;45     }46   }47 }

      到这一步已经实现任意两个图形相消除,接下来是——两个相同图形的消除。

    17. LLKMouseListener.java
       1 package com.edp.impl; 2  3 import java.awt.event.MouseAdapter; 4 import java.awt.event.MouseEvent; 5  6 import javax.swing.JTable; 7  8 public class LLKMouseListener extends MouseAdapter{ 9   /**10   1.相同图片能够消除11   2.在同一行或者同一列无障碍物可消除12   3.一个拐点可消除13   4.两个拐点可消除14   */15   public MyTableModel mtm;16   17   //1_4.发现消除的是一个,点一个就消掉一个18   //所以需要做下关联, 控制第一次还是第二次点击的操作19   public boolean flag = true;20   public int row1, column1, row2, column2;21   //3.鼠标监控22   public LLKMouseListener(MyTableModel mtm) {23     this.mtm = mtm;24   }25   26   public void mousePressed(MouseEvent e) {27     //1.相同图片能够消除28     // 1_1.需要知道自己点击的是表格哪个位置29     // 1_2.得到被选中行被选中列30     JTable table = (JTable) e.getSource();31     32     // 1_3.把指定位置的图片消除:去除路径33     String[][] saveDB = mtm.getSaveDB();34     35     if(flag){36       row1 = table.getSelectedRow();37       column1 = table.getSelectedColumn();38       flag = false;39     }else{40       row2 = table.getSelectedRow();41       column2 = table.getSelectedColumn();42       if((row1 != row2 || column1 != column2)){43         if(saveDB[row1][column1].equals(saveDB[row2][column2])){44           if(checkRow(row1,column1,row2,column2)||45               checkColumn(row1,column1,row2,column2)){46             saveDB[row1][column1] = "";47             saveDB[row2][column2] = "";48           }49         }50       }51       flag = true;52     }53   }54   55   //同行算法56   public boolean checkRow(int row1, int column1, int row2, int column2) {57     // 1.保证两个位置是同一行58     if (row1 == row2) {59       int minColumn = Math.min(column1, column2);60       int maxColumn = Math.max(column1, column2);61       // 寻找两个位置之间的所有位置是否为空62       for (int i = minColumn + 1; i < maxColumn; i++) {63         if (!"".equals(mtm.getSaveDB()[row1][i])) {64           return false;65         }66       }67       return true;68     }69     return false;70   }71   72   //同列算法73   public boolean checkColumn(int row1, int column1, int row2, int column2) {74     // 1.保证两个位置是同一列75     if (column1 == column2) {76       int minRow = Math.min(row1, row2);77       int maxRow = Math.max(row1, row2);78       // 寻找两个位置之间的所有位置是否为空79       for (int i = minRow + 1; i < maxRow; i++) {80         if (!"".equals(mtm.getSaveDB()[column1][i])) {81           return false;82         }83       }84       return true;85     }86     return false;87     88   }89   public boolean checkOnePoint(int row1, int column1, int row2, int column2) {90     return false;91     92   }93   public boolean checkTwoPoint(int row1, int column1, int row2, int column2) {94     return false;95   }96 97 }

       

    18. 继续增加代码,也就是限制消除的条件(对消除提条件),因为只有鼠标监听类有做修改,所以就只放这个类的代码了。
    19. 这里实现的行和列相同图片可以消除。还剩一个拐点和两个拐点。
    20. 在写出上述代码的时候一直用   "System.out.println();"语句进行反复测试才实现代码,而且在不断增加代码中,这种测试方法会一直用。