0

my code sets up a 6x6 array of JButtons when you press one of these JButtons a 6x1 JDialog box pops up offering 6 colour choices. when one of these is pressed the square clicked to open the JDialog box changes colour.

I want to write a piece of code so that you can have only one square of each colour in any row/column. At the minut the boolean i have stops you from setting the same colour to the same square (as when you click it it goes to black if it is any other colour).

the code is below. any help will be much appreciated. thanks

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.sql.*;
public class Grid5 extends JFrame implements ActionListener
{
        private ColourChooser paintBox = null;
        public static final int ROW = 6;
        public static final int COLUMN = 6;
        private static Grid5 grid;
        public static final String defaultName = "Black";
        public JButton[][] buttons; //makes an array called buttons
        public static void main(String[] args)// sets up a 6x6 grid
        {
            int rows = 6;
            int cols = 6;
            int size = 600;
            Grid5 grid = new Grid5(rows, cols);
            grid.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            grid.setPreferredSize(new Dimension(size, size));
            grid.pack();
            grid.setLocationRelativeTo(null);
            grid.setVisible(true);
        }
        // main
        public Grid5(int rows, int cols) // makes the 6x6 main grid a grid of JButtons
        {
            int rowSize = 6;
            int colSize = 6;
            int gridSize = 600;
            buttons = new JButton[rowSize][colSize];
            Container pane = getContentPane();
            pane.setLayout(new GridLayout(rows, cols));
            for(int j =0; j < rows; j++){
                for (int i = 0; i < cols; i++) {
                    buttons[j][i] = new JButton("");
                    buttons[j][i].setOpaque(true);
                    buttons[j][i].setBackground(Color.BLACK);
                    buttons[j][i].setActionCommand(j + " " + i);
                    buttons[j][i].setName("Black");
                    buttons[j][i].addActionListener(this);
                    pane.add(buttons[j][i]);
                }
            }
        }               //end of grid constructor

        public void actionPerformed(ActionEvent e) 
        {
            JButton button = (JButton) e.getSource();
            if ( paintBox != null && paintBox.isShowing())//stops more than one paintBox from opening
                paintBox.dispose();
            if( e.getSource() instanceof JButton){
                ((JButton)e.getSource()).setBackground(Color.BLACK);
            } 

            int rows = 6;
            int cols = 1;
            int size = 300;
            paintBox = new ColourChooser(grid, false, button);
            paintBox.setPreferredSize(new Dimension(size/3, size));
            paintBox.pack();
            paintBox.setVisible(true);
        }
}

class ColourChooser extends JDialog
{ 
    private JButton fillRed = new JButton("Red");
    private JButton fillYellow = new JButton("Yellow");
    private JButton fillBlue = new JButton("Blue");
    private JButton fillGreen = new JButton("Green");
    private JButton fillPurple = new JButton("Purple");
    private JButton fillBrown = new JButton("Brown");
    private JButton[] paintButton = {fillRed,fillYellow,fillBlue,fillGreen,fillPurple,fillBrown};
    private Color[] colours = {Color.RED, Color.YELLOW, Color.BLUE, Color.GREEN, new Color(102, 0, 102), new Color(102, 51, 0)};
    private JButton buttonPress;

    private int buttonsLeftRow ;
    private int buttonsLeftColumn ;
    private int row,column;

    public ColourChooser(final Grid5 frame, boolean isModal, JButton button)
    {

        buttonPress = button;
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(6, 1));
        for (int i = 0; i < paintButton.length; i++) {
            paintButton[i].setOpaque(true);
            paintButton[i].addActionListener(buttonAction);
            paintButton[i].setForeground(new Color(100,100,100));
            paintButton[i].setBackground(colours[i]);
            panel.add(paintButton[i]);
        }
        add(panel);
        pack();
    }
    private ActionListener buttonAction = new ActionListener()
    {
        public void actionPerformed(ActionEvent a)
        {
            JButton fill = (JButton) a.getSource(); 
            if(fill == fillRed){
                String colour = "Red";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(Color.RED);
                    buttonPress.setName("Red");
                    dispose();
                }
            }
            if(fill == fillYellow){
                String colour = "Yellow";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(Color.YELLOW);
                    buttonPress.setName("Yellow");
                    dispose();
                }
            }
            if(fill == fillBlue){
                String colour = "Blue";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(Color.BLUE);
                    buttonPress.setName("Blue");
                    dispose();
                }
            }
            if(fill == fillGreen){
                String colour = "Green";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(Color.GREEN);
                    buttonPress.setName("Green");
                    dispose();
                }
            }
            if(fill == fillPurple){
                String colour = "Purple";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(new Color(102, 0, 102));
                    buttonPress.setName("Purple");
                    dispose();
                }
            }
            if(fill.equals(fillBrown)){
                String colour = "Brown";
                if(checkColoursRow(colour)){
                    buttonPress.setBackground(new Color(102, 51, 0));
                    buttonPress.setName("Brown");
                    dispose();
                }
            } 
        }
    };

    private boolean checkColoursRow(String colour){
        String command = buttonPress.getActionCommand();
        String[] array = command.split(" ");
        int row = Integer.parseInt(array[0]);
         int column = Integer.parseInt(array[1]); 

        for(int i = 0; i<Grid5.COLUMN; i++){
            if (i != row)
            {
                if(buttonPress.getName().equals(colour))
                return false;   
            }
        }


        for (int i = 0; i  < Grid5.ROW; i++)
        {
            if (i != column)
            {
                if (buttonPress.getName().equals(colour))
                    return false;
            }   
        }
        return true;

        }
}

1 Answers1

5

You are almost there, just a bit of missing pieces

Step 1: You need to pass reference of current initialized Grid5 object to the ColorChooser. For this, change line

        paintBox = new ColourChooser(grid, false, button);

to

        paintBox = new ColourChooser(this, false, button);

Because the variable grid is never initialized, and this refers to current Grid5 object and that will be initialized. Declare a variable of type Grid5 in ColourChooser as Grid5 frame;

Step 2: In the constructor of ColourChooser

public ColourChooser(final Grid5 frame, boolean isModal, JButton button)

Assign parameter frame to local variable as this.frame = fame

This way, you have a reference to the Grid and its buttons in your color chooser

Once, that is done,

Step3: implement a method in your ColourChooser in similar lines of checkColoursRow to achieve what you are looking for. It is always good to consider naming for methods that return boolean.. As you may notice, it improves readability and avoids confusion.

So, a method may be like(you may improve below code, I gave a detailed implementation for clarity):

private boolean hasColorInRowOrCol(String color){
    String command = buttonPress.getActionCommand();
    String[] array = command.split(" ");
    int row = Integer.parseInt(array[0]);
    int column = Integer.parseInt(array[1]);  
    for(int cols=0; cols < Grid5.COLUMN;cols++) {
            //frame refers to currently initialized Grid5 object
        if(frame.buttons[row][cols].getName().equals(color)){
            return true;
        }
    }
    for(int rows=0;rows < Grid5.ROW; rows++){
            //frame refers to currently initialized Grid5 object
        if(frame.buttons[rows][column].getName().equals(color)){
            return true;
        }
    }
    return false;
}

Above method basically works through current row/coloumn and checks if the color is set as name for any of the buttons to the frame.

Step 4: Last piece is to call this method in your ActionListener buttonAction as in below example for each case:

  JButton fill = (JButton) a.getSource(); 
    if(fill == fillRed){
        String colour = "Red";
        if(!hasColorInRowOrCol(colour)){
            buttonPress.setBackground(Color.RED);
            buttonPress.setName("Red");
            dispose();
        }
    }
Community
  • 1
  • 1
ring bearer
  • 20,383
  • 7
  • 59
  • 72
  • i've added what you said but i'm getting an error saying identifier expected when i declare the variable Grid5 frame in line 68. not sure what it means very sorry i'm only new to java. – user1296913 Mar 30 '12 at 03:27
  • Add a variable declaration `private Grid5 frame;` after the line, say, `private JButton buttonPress;` in class `ColourChooser` - is this what you have done? – ring bearer Mar 30 '12 at 03:31
  • +1, exactly what I thought of, nice answer :-) – nIcE cOw Mar 30 '12 at 03:38