001/* 002 * Button.java 003 */ 004package minesweeper; 005 006import java.awt.*; 007import java.awt.event.*; 008//import java.awt.image.*; 009//import java.io.*; 010//import java.nio.file.*; 011//import javax.imageio.*; 012import javax.swing.*; 013//import java.util.*; 014import org.apache.logging.log4j.*; 015import java.util.Arrays; 016 017/** 018 * {@link Button} is a {@link JButton} for spaces / flags / mines. 019 * 020 * @author 2017-2018 APCS 021 * @author ADD @author TAG FOR EVERYONE WHO CONTRIBUTED TO THIS FILE 022 * @author <a href="https://github.com/wps-dpetty">David C. Petty</a> 023 */ 024public class Button extends JButton implements ActionListener { 025 026 //////////////////////////////// FIELDS //////////////////////////////// 027 028 /** 029 * log4j {@link Logger}. 030 */ 031 private static Logger logger = LogManager.getLogger(Minesweeper.SHORT); 032 /** 033 * This {@link Button}'s row. 034 */ 035 private int row; 036 /** 037 * This {@link Button}'s column. 038 */ 039 private int col; 040 041 ///////////////////////////// CONSTRUCTORS ///////////////////////////// 042 043 /** 044 * Create square {@link Button}. 045 * 046 * @param row number of row 047 * @param col number of column 048 * @param side minimum size of square button 049 */ 050 public Button(int row, int col, int side) { 051 super(); 052 this.row = row; 053 this.col = col; 054 Dimension initialSize = new Dimension(side, side); 055 setPreferredSize(initialSize); 056 setSize(initialSize); 057 setActionCommand(row, col); 058 addActionListener(this); 059 setBorderPainted(false); 060 setOpaque(true); 061 setVisible(true); 062 logger.info("{}:{}:\"{}\":({})", 063 getClass(), initialSize, getActionCommand(), paramString()); 064 } 065 066 //////////////////////////////// METHODS /////////////////////////////// 067 068 /** 069 * Invoked when an action occurs. 070 * 071 * @param e event triggering action 072 */ 073 public void actionPerformed(ActionEvent e) { 074 logger.info("{}:{}", getClass(), e); 075 Point point = parseActionCommand(e.getActionCommand()); 076 // RED_FLAG: simply something to do when the mouse is clicked 077 Button button = Main.getGrid().findButton(point.x, point.y); 078 if (button != null) // RED_FLAG: what to do if button not found? 079 { 080 //button.setBackground(Color.RED); 081 Images[] images = {Images.COVER, Images.MINE, Images.FLAG, 082 Images.NUMBER1, Images.NUMBER2, Images.NUMBER3, Images.NUMBER4, 083 Images.NUMBER5, Images.NUMBER6, Images.NUMBER7, Images.NUMBER8,}; 084 Images image = images[0]; 085 System.out.print(Arrays.deepToString(Minesweeper.getGameArray())); 086 if (Minesweeper.getGameArray()[row][col].getIsMine()) 087 { 088 image = images[2]; 089 Main.youDied(); 090 } 091 else if (Minesweeper.getGameArray()[row][col].getTileValue() == 0) {} 092 // to do 093 else 094 image = images[Minesweeper.getGameArray()[row][col].getTileValue() + 2]; 095 } 096 } 097 098 /** 099 * Paint the component using a {@link Graphics} rendering object. 100 * 101 * @param g the Graphics rendering object 102 * @to.do fix image repainting 103 */ 104 @Override 105 public void paintComponent(Graphics g) { 106 super.paintComponent(g); 107 // TODO: this paints all the images randomly... which is not correct 108 Images[] images = {Images.COVER, Images.MINE, Images.FLAG, 109 Images.NUMBER1, Images.NUMBER2, Images.NUMBER3, Images.NUMBER4, 110 Images.NUMBER5, Images.NUMBER6, Images.NUMBER7, Images.NUMBER8,}; 111 Images image = images[0]; 112 g.drawImage(image.image(), 0, 0, getWidth(), getHeight(), null); 113 } 114 115 /** 116 * Resizes this component so that it has width <code>width</code> and 117 * height <code>height</code>. This method changes layout-related 118 * information, and therefore, invalidates the component hierarchy. 119 * 120 * @param width new width of this component in pixels 121 * @param height new height of this component in pixels 122 */ 123 @Override 124 public void setSize(int width, int height) { 125 logger.trace("{}.setSize: (from) {} (to) {}", 126 getClass(), getSize(), new Dimension(width, height)); 127 int side = Math.min(width, height); 128 Dimension size = new Dimension(side, side); 129 super.setSize(side, side); 130 setPreferredSize(size); 131 } 132 133 /** 134 * Resizes this component so that it has width <code>size.width</code> and 135 * height <code>size.height</code>. This method changes layout-related 136 * information, and therefore, invalidates the component hierarchy. 137 * 138 * @param size dimension specifying the new size of this component 139 */ 140 @Override 141 public void setSize(Dimension size) { 142 // RED_FLAG: setSize(Dimension) calls setSize(int, int) else infinite 143 // recursion 144 setSize(size.width, size.height); 145 } 146 147 /** 148 * Return {@link String} representation of <code>this</code>. 149 * 150 * @return {@link String} representation of <code>this</code> 151 */ 152 @Override 153 public String toString() { 154 return new StringBuilder() 155 .append(getClass().getName()).append(":") 156 .append(getLocation()).append(":").append(getSize()).append(":") 157 .append("\"").append(getActionCommand()).append("\"") 158 .toString(); 159 } 160 161 /** 162 * {@link JButton#setActionCommand(java.lang.String) 163 * setActionCommand}("<code>row</code>,<code>col</code>"). 164 * 165 * @param row row of this {@link Button} 166 * @param col column of this {@link Button} 167 */ 168 public void setActionCommand(int row, int col) { 169 setActionCommand(row + "," + col); 170 } 171 172 /** 173 * Return (<code>row</code>,<code>col</code>) {@link Point} parsed from 174 * <code>actionCommand</code>. 175 * 176 * @param actionCommand "<code>row</code>,<code>col</code>" {@link String} 177 * @return (<code>row</code>, <code>col</code>) {@link Point} 178 */ 179 public static Point parseActionCommand(String actionCommand) { 180 int comma = actionCommand.indexOf(","); 181 assert comma > 0 && comma < actionCommand.length() 182 : "bad button command: \"" + actionCommand + "\""; 183 return new Point( 184 new Integer(actionCommand.substring(0, comma)), 185 new Integer(actionCommand.substring(comma + 1))); 186 } 187}