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}