SaoLei.java
package saolei; import java.awt.AWTEvent; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.io.Serializable; import java.util.Random; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.border.BevelBorder; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import util.MyAWTEventListener; import util.ObjectUtil; public class SaoLei extends JFrame implements Serializable { /** * */ private static final long serialVersionUID = 5977722980538750979L; static JTable table; static JTable table2; static JPanel desktop = new JPanel(); static SaoLeiTableModule tbModule; static int ROW_COUNT = 11; static int COL_COUNT = 20; static int LEI_NUMS = 0; static int LEI_LEFT = 0; static Random LEI_RANDOM = new Random(); static SaoLeiRandomIndex RANDOM_INDEX; static boolean GAME_START = false; static int LEVEL = 0; public static Object[][] dataArr_S = new Object[ROW_COUNT][COL_COUNT]; public SaoLei() { super(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void initLocation() { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int screenWitdth = screenSize.width; int screenHeight = screenSize.height; int width = COL_COUNT * 25; int height = ROW_COUNT * 25 + 100; setSize(width, height); setLocation((screenWitdth - width) / 2, (screenHeight - height) / 2); } public void configuratLevel() { switch (LEVEL) { case 2:// hard ROW_COUNT = 31; COL_COUNT = 50; LEI_NUMS = 200; break; case 1:// normal ROW_COUNT = 21; COL_COUNT = 35; LEI_NUMS = 120; break; case 0:// easy ROW_COUNT = 11; COL_COUNT = 20; LEI_NUMS = 26; default: break; } } public static void main(String[] args) { SaoLei myFrame = new SaoLei(); myFrame.buildFrame(); myFrame.newGame(); } JDialog dialog = null; public void newGame() { if (dialog != null) { dialog.dispose(); } configuratLevel(); tbModule = new SaoLeiTableModule(ROW_COUNT, COL_COUNT); table.setModel(tbModule); for (int i = 0; i < table.getColumnCount(); i++) { table.getColumnModel().getColumn(i).setPreferredWidth(22); } table.setRowHeight(22); table.setRowHeight(0, 1); for (int i = 1; i < table.getModel().getRowCount(); i++) { for (int j = 0; j < table.getModel().getColumnCount(); j++) { table.setValueAt(null, i, j); } } dataArr_S = new Object[ROW_COUNT][COL_COUNT]; tcr.initDisFlagArr(ROW_COUNT, COL_COUNT); table.repaint(); GAME_START = true; random(); loadNumbers(); initLocation(); desktop.repaint(); setVisible(true); } public void buildFrame() { desktop = new JPanel(); desktop.setLayout(new BoxLayout(desktop, BoxLayout.Y_AXIS)); JPanel tbPanel = new JPanel(); tbPanel.add(loadTable()); desktop.add(tbPanel); desktop.add(Box.createHorizontalStrut(50)); // JPanel tbPanel2 = new JPanel(); tbPanel2.add(loadTable2()); // desktop.add(tbPanel2); JPanel btnPanel = new JPanel(); btnPanel.add(loadButton()); desktop.add(btnPanel); desktop.add(Box.createHorizontalStrut(50)); getContentPane().add(desktop); Toolkit.getDefaultToolkit().addAWTEventListener( new MyAWTEventListener() { public void keyPressed(KeyEvent e) { keyEventToolkit(e); } }, AWTEvent.KEY_EVENT_MASK); } public void keyEventToolkit(KeyEvent e) { // System.out.println(e.getKeyCode() + ":" + e.getKeyChar()); switch (e.getKeyCode()) { case 27:// esc break; case 8:// backspace case 112:// 112 F1 newGame(); break; default: break; } } Color color = new Color(232, 232, 232); SaoLeiTableCellRenderer tcr = new SaoLeiTableCellRenderer();// 設置table內容居中 static JLabel jtf = new JLabel(); public JPanel loadTable() { JPanel fr4 = new JPanel(); fr4.setBorder(new TitledBorder("掃雷")); fr4.setLayout(new BoxLayout(fr4, BoxLayout.Y_AXIS)); table = new JTable(); table.setRowSelectionAllowed(false); table.setColumnSelectionAllowed(false); table.setDefaultRenderer(Object.class, tcr); // table.setGridColor(color); Border bor = new BevelBorder(BevelBorder.LOWERED); table.setBorder(bor); // table.setShowHorizontalLines(false); // table.setShowVerticalLines(false); Dimension abc = table.getIntercellSpacing(); abc.setSize(4, 4); table.setIntercellSpacing(abc); SaoLeiMouseListener mouse = new SaoLeiMouseListener() { public void mouseClicked(MouseEvent e) { if (!GAME_START) { showDialog("遊戲已結束請點擊開啓新遊戲", "提示", "info"); desktop.repaint(); return; } int col = table.columnAtPoint(e.getPoint()); int row = table.rowAtPoint(e.getPoint()); // 1 left click // 2 scroll click // 3 right click if (e.getButton() == 1) { if (table.getValueAt(row, col) != null && SaoLeiTableCellRenderer.MARK_LIST.contains(table .getValueAt(row, col))) { int returnCode = JOptionPane.showConfirmDialog(table, "該欄位被標記,是否繼續點開?", "確認", JOptionPane.YES_NO_OPTION); // showDialog("該欄位被標記,是否繼續點開?", "確認", "confirm"); // 0:Yes 1:No; -1:Colse; desktop.repaint(); if (returnCode != 0) { return; } } tcr.INIT_FLAG = false; // 清除空欄 // 如果點錯了那麼GAME OVER if (compareData(SaoLeiTableCellRenderer.LEI, dataArr_S[row][col])) { for (int rowIndex = 0; rowIndex < ROW_COUNT; rowIndex++) { for (int colIndex = 0; colIndex < COL_COUNT; colIndex++) { if (ObjectUtil.compareData( dataArr_S[rowIndex][colIndex], SaoLeiTableCellRenderer.LEI)) { table.setValueAt( SaoLeiTableCellRenderer.LEI, rowIndex, colIndex); } } } GAME_START = false; showDialog("GAME OVER!", "遊戲結束", "error"); desktop.repaint(); return; } clearRange(row, col); // 判斷通關遊戲結束 if (checkPass()) { GAME_START = false; showDialog("恭喜找出所有的地雷", "遊戲結束", "info"); desktop.repaint(); return; } } else if (e.getButton() == 3) { if (table.getValueAt(row, col) == null) { LEI_LEFT--; table.setValueAt(SaoLeiTableCellRenderer.MARK_LIST .get(0), row, col); } else if (String.valueOf(table.getValueAt(row, col)) .equals(SaoLeiTableCellRenderer.MARK_LIST.get(0))) { LEI_LEFT++; table.setValueAt(SaoLeiTableCellRenderer.MARK_LIST .get(1), row, col); } else if (String.valueOf(table.getValueAt(row, col)) .equals(SaoLeiTableCellRenderer.MARK_LIST.get(1))) { // LEI_LEFT++; table.setValueAt(null, row, col); } displayLeftLeiNums(); } desktop.repaint(); } }; table.addMouseListener(mouse); table.addMouseMotionListener(mouse); JPanel fr5 = new JPanel(); JLabel jlb = new JLabel(); jlb.setHorizontalAlignment(SwingConstants.CENTER); jlb.setVerticalAlignment(SwingConstants.CENTER); jlb.setText("剩餘地雷數:"); fr5.add(jlb); jtf.setPreferredSize(new Dimension(40, 18)); displayLeftLeiNums(); jtf.setFont(new Font("", Font.BOLD, 18)); jtf.setForeground(Color.RED); jtf.setOpaque(true); jtf.setBackground(Color.BLACK); jtf.setHorizontalAlignment(SwingConstants.CENTER); fr5.add(jtf); fr4.add(fr5); fr4.add(table); return fr4; } public void showDialog(String msg, String title, String type) { if ("error".equals(type)) { dialog = new JOptionPane(msg, JOptionPane.ERROR_MESSAGE) .createDialog(table, title); } else if ("confirm".equals(type)) { dialog = new JOptionPane(msg, JOptionPane.YES_NO_OPTION) .createDialog(table, title); } else {// info dialog = new JOptionPane(msg, JOptionPane.INFORMATION_MESSAGE) .createDialog(table, title); } dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setAlwaysOnTop(true); dialog.setModal(false); dialog.setVisible(true); } // 判斷有沒有成功找出所有的雷 public static boolean checkPass() { // Table的Header行不要 for (int row = 1; row < ROW_COUNT; row++) { for (int col = 0; col < COL_COUNT; col++) { if (!compareData(dataArr_S[row][col], SaoLeiTableCellRenderer.LEI) && !verifyCell(dataArr_S[row][col], table.getValueAt( row, col))) { return false; } } } return true; } public static boolean verifyCell(Object o1, Object o2) { String val1 = o1 == null ? "" : String.valueOf(o1); String val2 = o2 == null ? "" : String.valueOf(o2); if (String.valueOf(val1).equals(String.valueOf(val2))) { return true; } return false; } public static void displayLeftLeiNums() { String SCORE_S = String.valueOf(LEI_LEFT); for (int i = 3; i > String.valueOf(LEI_LEFT).length(); i--) { SCORE_S = "0" + SCORE_S; } jtf.setText(SCORE_S); } public void clearRange(int row, int col) { // 1 2 3 // 4 5 6 // 7 8 9 // 點擊編號5,遇到數字則終止 // 判斷1,2,3,4,6,7,8,9,遇到數字則終止 // 編號5,賦值當前單元格 Object value = dataArr_S[row][col] == null ? "" : dataArr_S[row][col]; table.setValueAt(value, row, col); // 如果不是空那麼直接返回 if (!checkEmpty(dataArr_S[row][col])) { return; } // 如果是空值,那麼繼續判斷 // 判斷九宮格內的空格 for (int rIndex = row - 1; rIndex <= row + 1; rIndex++) { for (int cIndex = col - 1; cIndex <= col + 1; cIndex++) { // 判斷有無超出邊界 if (rIndex < 1 || rIndex >= ROW_COUNT || cIndex < 0 || cIndex >= COL_COUNT) { continue; } if ((rIndex == row && cIndex == col)) {// 5 continue; } // 如果已經判斷過了那麼直接跳過 if (table.getValueAt(rIndex, cIndex) != null) { continue; } Object value2 = dataArr_S[rIndex][cIndex] == null ? "" : dataArr_S[rIndex][cIndex]; // 如果2,4,6,8欄位爲空,那麼迭代該欄位 if (checkEmpty(dataArr_S[rIndex][cIndex])) { clearRange(rIndex, cIndex); } else { // 判斷是不是雷,雷不能直接顯示 if (compareData(SaoLeiTableCellRenderer.LEI, dataArr_S[rIndex][cIndex])) { continue; } else {// 顯示數字 table.setValueAt(value2, rIndex, cIndex); } } } } } JRadioButton radioButton1 = new JRadioButton("Easy");// 創建單選按鈕 JRadioButton radioButton2 = new JRadioButton("Normal");// 創建單選按鈕 JRadioButton radioButton3 = new JRadioButton("Hard");// 創建單選按鈕 public JPanel loadButton() { JPanel fr2 = new JPanel(); fr2.setSize(100, 100); fr2.setLayout(new FlowLayout(FlowLayout.CENTER, 2, 3));// 設置內容面板爲流式佈局 fr2.setBorder(new EmptyBorder(5, 5, 5, 5));// 設置面板的邊框 fr2.add(radioButton1);// 應用單選按鈕 fr2.add(radioButton2);// 應用單選按鈕 fr2.add(radioButton3);// 應用單選按鈕 switch (LEVEL) { case 2: radioButton3.setSelected(true); break; case 1: radioButton2.setSelected(true); break; case 0: default: radioButton1.setSelected(true); break; } ButtonGroup group = new ButtonGroup();// 創建單選按鈕組 group.add(radioButton1);// 將radioButton1增加到單選按鈕組中 group.add(radioButton2);// 將radioButton2增加到單選按鈕組中 group.add(radioButton3);// 將radioButton3增加到單選按鈕組中 ItemListener radioListener = new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getSource() == radioButton1) { LEVEL = 0;// easy } else if (e.getSource() == radioButton2) { LEVEL = 1;// normal } else if (e.getSource() == radioButton3) { LEVEL = 2;// hard } } }; radioButton1.addItemListener(radioListener); radioButton2.addItemListener(radioListener); radioButton3.addItemListener(radioListener); fr2.add(Box.createHorizontalStrut(30)); JButton jbtnBegin = new JButton("New Game"); jbtnBegin.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { newGame(); } }); fr2.add(jbtnBegin); return fr2; } public void random() { RANDOM_INDEX = new SaoLeiRandomIndex((ROW_COUNT - 1) * COL_COUNT); LEI_LEFT = 0; for (int i = 0; i < LEI_NUMS; i++) { // 如果 int index = RANDOM_INDEX.randomIndex(); int row = index / COL_COUNT; int col = index % COL_COUNT; dataArr_S[row + 1][col] = SaoLeiTableCellRenderer.LEI; LEI_LEFT++; } displayLeftLeiNums(); desktop.repaint(); } public void loadNumbers() { Object[][] dataArr = new Object[ROW_COUNT][COL_COUNT]; for (int rowIndex = 1; rowIndex < ROW_COUNT; rowIndex++) { for (int colIndex = 0; colIndex < COL_COUNT; colIndex++) { String valC = String.valueOf(dataArr_S[rowIndex][colIndex]); // 如果當前單元格是雷,那麼直接把雷放到新數組 if (compareData(SaoLeiTableCellRenderer.LEI, valC)) { dataArr[rowIndex][colIndex] = SaoLeiTableCellRenderer.LEI; } else {// 如果不是雷,那麼判斷周圍九宮格內有幾個雷 int num = 0; for (int x = colIndex - 1; x <= colIndex + 1; x++) {// 橫座標 if (!(x < COL_COUNT && x >= 0)) { continue; } for (int y = rowIndex - 1; y <= rowIndex + 1; y++) {// 縱座標 if (!(y < ROW_COUNT && y >= 0)) { continue; } String valJiuGong = String.valueOf(dataArr_S[y][x]); if (compareData(SaoLeiTableCellRenderer.LEI, valJiuGong)) { num++; } } } if (num > 0) { dataArr[rowIndex][colIndex] = num; } } } } // tbModule.setDataArr(dataArr); dataArr_S = dataArr; } public boolean checkEmpty(Object cellV) { if (cellV == null || String.valueOf(cellV).length() == 0) { return true; } return false; } public static boolean compareData(Object val1, Object val2) { if ((val1 == null && val2 == null) || (String.valueOf(val1).equals(String.valueOf(val2)))) { return true; } return false; } public boolean compareArr(Object[][] dataArr1, Object[][] dataArr2) { for (int rowIndex = 1; rowIndex < ROW_COUNT; rowIndex++) { for (int colIndex = 0; colIndex < COL_COUNT; colIndex++) { if (!compareData(dataArr1[rowIndex][colIndex], dataArr2[rowIndex][colIndex])) { return false; } } } return true; } }
MouseMotion.java
package saolei; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; public class MouseMotion implements MouseMotionListener { public void mouseDragged(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub } }
SaoLeiKeyListener.java
package saolei; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; public class SaoLeiKeyListener implements KeyListener { public void keyPressed(KeyEvent e) { System.out.println(e.getKeyCode()); // 37 left // 38 up // 39 right // 40 down } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } }
SaoLeiMouseListener.java
package saolei; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; public class SaoLeiMouseListener implements MouseListener,MouseMotionListener { public void mouseClicked(MouseEvent e) { // 1 left click // 2 scroll click // 3 right click System.out.println(e.getButton()); } public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseDragged(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseMoved(MouseEvent arg0) { // TODO Auto-generated method stub } }
SaoLeiRandomIndex.java
package saolei; import java.util.ArrayList; import java.util.List; import java.util.Random; public class SaoLeiRandomIndex { List<Integer> indexL = null; List<Integer> choosenL = null; Random random = new Random(); private int maxIndex = 0; public SaoLeiRandomIndex(int maxIndex) { this.maxIndex = maxIndex; init(); } private void init() { indexL = new ArrayList<Integer>(); choosenL = new ArrayList<Integer>(); for (int i = 0; i < maxIndex; i++) { indexL.add(i); } } public void addIndexL(Integer i) { if (indexL == null) { indexL = new ArrayList<Integer>(); } indexL.add(i); } public void addChoosneL(Integer i) { if (choosenL == null) { choosenL = new ArrayList<Integer>(); } choosenL.add(i); } public void clear() { indexL = new ArrayList<Integer>(); choosenL = new ArrayList<Integer>(); } public int randomIndex() { if (indexL.isEmpty()) { System.out.println("No more data!"); return 0; } int index = random.nextInt(indexL.size()); int number = indexL.get(index); choosenL.add(number); indexL.remove(index); return number; } public static void main(String args[]) { SaoLeiRandomIndex a = new SaoLeiRandomIndex(16); a.init(); while (a.indexL.size() > 0) { System.out.println(a.randomIndex()); } System.out.println(a.indexL); } }
SaoLeiTableCellRenderer.java
package saolei; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.table.DefaultTableCellRenderer; import util.ObjectUtil; public class SaoLeiTableCellRenderer extends DefaultTableCellRenderer implements Serializable { /** * serialVersionUID */ private static final long serialVersionUID = 7075922603764573186L; public boolean INIT_FLAG = true; static String LEI = "★"; static List<String> MARK_LIST = null; public void initDisFlagArr(int rowCount, int colCount) { INIT_FLAG = true; } public SaoLeiTableCellRenderer() { setOpaque(true); if (MARK_LIST == null) { MARK_LIST = new ArrayList<String>(); MARK_LIST.add("●"); MARK_LIST.add("?"); } } Color color = new Color(232, 232, 232); public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component editor = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); setHorizontalAlignment(SwingConstants.CENTER); setVerticalAlignment(SwingConstants.CENTER); editor.setForeground(Color.BLACK); editor.setBackground(color); //editor.setFont(new Font("Arial", Font.BOLD, 16)); editor.setFont(new Font("宋體", Font.BOLD, 14)); if (row == 0) { editor.setBackground(Color.LIGHT_GRAY); } else { if (INIT_FLAG) { editor.setBackground(color); } else { if (table.getValueAt(row, column) != null && !MARK_LIST.contains(table.getValueAt(row, column))) { editor.setBackground(Color.WHITE); } else { editor.setBackground(color); } if (ObjectUtil.compareData(LEI, table.getValueAt(row, column))) { editor.setForeground(Color.RED); editor.setFont(new Font("宋體", Font.BOLD, 14)); } if (ObjectUtil.compareData(MARK_LIST.get(0), table.getValueAt( row, column))) { editor.setFont(new Font("宋體", Font.BOLD, 14)); //editor.setForeground(Color.RED); } } } return editor; } }
SaoLeiTableModule.java
package saolei; import java.io.Serializable; import javax.swing.table.AbstractTableModel; public class SaoLeiTableModule extends AbstractTableModel implements Serializable { /** * */ private static final long serialVersionUID = 1978547795796513859L; private int rowCount = 1; private int columnCount = 1; private static Object[][] dataArr = null; public SaoLeiTableModule(int rowCount, int columnCount) { if (columnCount > 1) { this.columnCount = columnCount; } else { this.columnCount = 1; } if (rowCount > 1) { this.rowCount = rowCount; } else { this.rowCount = 1; } initTableDataAndHearder(); } public Class<?> getColumnClass(int columnIndex) { if (getValueAt(0, columnIndex) != null) { return getValueAt(0, columnIndex).getClass(); } else { return String.class; } } public String getColumnName(int columnIndex) { return " 第" + columnIndex + "列"; } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (rowIndex >= rowCount) { new Exception("Row Index Outbound!").printStackTrace(); } if (columnIndex >= columnCount) { new Exception("Column Index Outbound!").printStackTrace(); } if (dataArr == null) { initTableDataAndHearder(); } dataArr[rowIndex][columnIndex] = aValue; fireTableCellUpdated(rowIndex, columnIndex); } public void initTableDataAndHearder() { dataArr = new Object[rowCount][columnCount]; /*for (int col = 0; col < columnCount; col++) { dataArr[0][col] = "C" + col; } for (int col = 0; col < rowCount; col++) { dataArr[col][0] = "R" + col; }*/ } public Object getValueAt(int rowIndex, int columnIndex) { if (dataArr == null) { initTableDataAndHearder(); } Object val = dataArr[rowIndex][columnIndex]; return val; } public boolean isCellEditable(int rowIndex, int columnIndex) { return false; } public int getRowCount() { return rowCount; } public int getColumnCount() { return columnCount; } public Object[][] getDataArr() { return dataArr; } public void setDataArr(Object[][] dataArr) { SaoLeiTableModule.dataArr = dataArr; } }