Swapping 2d array of buttons in GUI - Java - java

I am trying to find a way to either SWITCH the buttons or SWAP the button icons in a 2D array of buttons. I am attempting to create a board game and move pieces around.
I'm not sure if my logic is just completely off here but my though process is.. Create a Gamepiece class that extends JButton. Pass those buttons into a 2d array and add that button to the GridLayout.
Now, I feel like swapping the icons on the buttons is simpler but I cant seem to figure out how to do it correctly.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Board implements ActionListener {
private int p1;
private int p2;
private int fromRow;
private int fromCol;
private int toRow;
private int toCol;
private JPanel grid = new JPanel(new GridLayout(8,8));
private JFrame jf = new JFrame();
GamePieces gp;
private boolean isFirstClick = true;
Icon eagles = new ImageIcon("eagles.png");
Icon cowboys = new ImageIcon("cowboys.png");
GamePieces boardGame [][] = new GamePieces [8][8];
int board [][] = new int [][]{{1,1,1,1,0,0,0,0},
{1,1,1,0,0,0,0,0},
{1,1,0,0,0,0,0,0},
{1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,2},
{0,0,0,0,0,0,2,2},
{0,0,0,0,0,2,2,2},
{0,0,0,0,2,2,2,2}};
///////////////////////////////////////////////////////////////////
public Board(){
jf.setTitle("Board Game");
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(640,640);
JMenuBar menuBar = new JMenuBar();
jf.setJMenuBar(menuBar);
JMenu file = new JMenu("File");
JMenu about = new JMenu("About");
menuBar.add(file);
menuBar.add(about);
createBoard();
jf.setVisible(true);
}// end constructor
////////////////////////////////////////////////////////////////////
public void movePiece(){
for(int row = 0; row < boardGame.length; row++){
for(int col = 0; col < boardGame.length; col++){
boardGame[toRow][toCol] = boardGame[fromRow][fromCol];
gp = new GamePieces(fromRow,fromCol);
gp.setIcon(eagles);
boardGame[toRow][toCol] = gp;
jf.repaint();
}
}
}
/////////////////////////////////////////////////////////
public void actionPerformed(ActionEvent ae){
for(int row = 0; row < boardGame.length; row++){
for(int col = 0; col < boardGame.length; col++){
if(ae.getSource() == boardGame[row][col]){
if(isFirstClick){
fromRow = boardGame[row][col].getRow();
fromCol = boardGame[row][col].getCol();
isFirstClick = false;
System.out.println("First Row " + boardGame[row][col].getRow() + " Col " + boardGame[row][col].getCol());
}
else {
toRow = boardGame[row][col].getRow();
toCol = boardGame[row][col].getCol();
System.out.println("Second Row " + boardGame[row][col].getRow() + " Col " + boardGame[row][col].getCol());
this.movePiece();
}
}
}
}
}
///////////////////////////////////////////////////////
public void createBoard(){
for(int row = 0; row < board.length; row++){
for(int col = 0; col < board.length; col++){
if (board[row][col] == 1){
gp = new GamePieces(row,col);
gp.setIcon(eagles);
boardGame[row][col] = gp;
grid.add(boardGame[row][col]);
boardGame[row][col].addActionListener(this);
}
else if (board[row][col] == 0){
gp = new GamePieces(row,col);
boardGame[row][col] = gp;
grid.add(boardGame[row][col]);
boardGame[row][col].addActionListener(this);
}
else if(board[row][col] == 2){
gp = new GamePieces(row,col);
gp.setIcon(cowboys);
boardGame[row][col] = gp;
grid.add(boardGame[row][col]);
boardGame[row][col].addActionListener(this);
}
}
}
jf.add(grid);
}
class GamePieces extends JButton {
private int row;
private int col;
private String player;
public GamePieces(int row, int col){
this.row = row;
this.col = col;
}
public int getRow(){
return row;
}
public int getCol(){
return col;
}
public String getPlayer(){
return player;
}
}
public static void main(String [] args){
Board Halmas = new Board();
}
}

No, don't swap buttons as there's no need, and no benefit to doing this. Instead use an MVC or Model-View-Control program structure and swap Icons held by JButtons or JLabels (my preference) as dictated by changes in the model's state.
Regardless of what overall technique you use, swap your icons, not your buttons.

Related

How to update the position of snakes and ladders in an 2D array code?

public class ChutesAndLadders2d {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[][] numbersOnBoard = new int [6][6];
boardSetUpA (numbersOnBoard);
printTwoD(numbersOnBoard);
}
public static void boardSetUpA (int[][]twoD) {
//Square with even size
//even rows
for (int row = 0;row<twoD.length; row ++) {
if (row %2 ==0) {
int num = twoD.length*(twoD.length-row);
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num--;
}
}//
else {
int num = twoD.length*(twoD.length-(row + 1))+ 1;
for (int col = 0; col<twoD[row].length; col ++ ) {
twoD[row][col] = num;
num++;
}
}
}//for row
}//
public static void printTwoD(int [][] array){
for (int row = 0; row < array.length; row++){
for (int column = 0; column < array[row].length; column++){
System.out.print(array[row][column] + "\t");
}
System.out.println();
}
}
public static void boardDetails(String[][]board) {
for (int row = 0;row<board.length; row++){
for (int col = 0;col<board[row].length; col++){
if( col+2 == row||col+1 == row*2 ){
board[row][col] = "Lad"; // Append value
}
else if (col*2 == row|| row*2 == col){
board[row][col] = "Cht";// Append value
}
else {
board[row][col] = " ";
}
}
board[board.length-1][0] = "Start";
if (board.length%2 ==0) {
board[0][0] = "End";}
else {
board[0][board.length-1]="End";
}
}
}
public static void printBoard (int[][]twoD, String[][]strTwoD) {
//Printing
for (int row = 0;row<twoD.length;row++) {
for (int col = 0;col<twoD[row].length;col++) {
System.out.print(twoD[row][col] + " "+strTwoD[row][col]+"\t\t");
}
System.out.println("\n");
}
}
}
This is the starter code I have for setting up the snakes and ladders game. I also tried to set the chutes/snakes and ladders on the board but it is not printing. How should I fix it and how do I develop this code to have three methods: update the moves of a player once he reaches a snake, a ladder, and once he rolls his die, from one place to another?
Is it possible to implement a Shutes & Ladders game using a 2D Array? For sure! Does that make sense in an object-oriented language such as Java? I dont know ....
What do you need for that?
A square board with e.g. 36 playing fields.
Connections between two playing fields. (shutes and ladders)
Pawns and a dice.
A renderer that outputs the playing field (as text or graphics).
A program that allows input and connects everything to a functioning game.
Here is an example that works with a List instead of an Array. That can certainly be changed if it is necessary for your purposes.
I hope this is of some help to you.
P.S .: After the start, the board is displayed with field numbers. Shutes are shown as red lines. Ladders as green lines. Keys 1-6 on the keyboard simulate rolling the dice..
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.*;
public class ChutesAndLadders2d {
public static void main(String[] args) {
JFrame frame = new JFrame("Chutes and Ladders 2D");
Game game = new ChutesAndLadders2d().new Game();
game.setPreferredSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setContentPane(game);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#SuppressWarnings("serial")
class Game extends JPanel{
private final Font defaultFont = new Font("Arial", Font.PLAIN, 16);
private final BasicStroke stroke = new BasicStroke(4f);
private static final int SCALE = 64;
// board and pawns
private final Board board = new Board(6);
private final List<Pawn> pawns = new ArrayList<>();
public Game(){
setFocusable(true); // receive Keyboard-Events
addKeyListener(new KeyAdapter(){
#Override
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if(c >= '1' && c <= '6'){
int steps = Integer.parseInt(Character.toString(c));
Pawn pawn = pawns.get(0);
pawn.move(steps);
Field field = board.get(pawn.fieldIndex);
if(field.targetKind() != Kind.NONE){
pawn.move(field.getTarget().index - field.index);
}
repaint();
}
}
});
board.connect(5, 12); // Ladder 5 -> 12
board.connect(8, 4); // Shute 8 -> 4
board.connect(15, 32); // Ladder 15 -> 32
board.connect(35, 17); // Shute 35 -> 17
board.connect(23, 30); // Ladder 23 -> 30
pawns.add(new Pawn(Color.BLUE, board.size() - 1));
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
setFont(defaultFont);
for(Field field : board){
Point p = field.getLocation();
g2d.drawRect(p.x * SCALE, p.y * SCALE, SCALE, SCALE);
g2d.drawString(field.text, p.x * SCALE + 24, p.y * SCALE + 40);
}
for(Field field : board){
if(field.targetKind() != Kind.NONE){
g2d.setColor(field.targetKind() == Kind.LADDER ? Color.GREEN : Color.RED);
g2d.setStroke(stroke);
Point source = field.getLocation();
Point target = field.getTarget().getLocation();
g2d.drawLine(source.x * SCALE + 40, source.y * SCALE + 24, target.x * SCALE + 40, target.y * SCALE + 24);
}
}
for(Pawn pawn : pawns){
Point loc = board.get(pawn.fieldIndex).getLocation();
g2d.setColor(pawn.color);
g2d.fillOval(loc.x * SCALE + 32, loc.y * SCALE + 32, 16, 16);
}
}
}
class Board implements Iterable<Field>{
private final List<Field> fields = new ArrayList<>();
public Board(int size){
for(int index = 0; index < size * size; index++)
fields.add(new Field(index, size));
}
public Field get(int index){
return fields.get(index);
}
public void connect(int startFieldnumber, int targetFieldnumber){
get(startFieldnumber - 1).setTarget(get(targetFieldnumber - 1));
}
#Override
public Iterator<Field> iterator() {
return fields.iterator();
}
public int size(){
return fields.size();
}
}
class Field{
final int index;
final String text;
final int size;
private Field target;
public Field(int index, int size){
this.index = index;
this.size = size;
text = "" + (index + 1);
}
public void setTarget(Field target){
if(target == this) return;
this.target = target;
}
public Field getTarget(){
return target;
}
public Kind targetKind(){
if(target == null) return Kind.NONE;
return index < target.index ? Kind.LADDER : Kind.SHUTE;
}
public Point getLocation(){
int x = index % size;
int y = index / size;
if(y % 2 != 0) x = size - x - 1;
return new Point(x, size - y - 1);
}
}
class Pawn{
int fieldIndex = 0;
int maxIndex;
Color color;
public Pawn(Color color, int maxIndex){
this.color = color;
this.maxIndex = maxIndex;
}
public void move(int steps){
fieldIndex += steps;
if(fieldIndex < 0) fieldIndex = 0;
if(fieldIndex > maxIndex) fieldIndex = maxIndex;
}
}
enum Kind{
NONE, SHUTE, LADDER
}
}

Background of chess board button is not set to black color

Here is my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ChessBoardGUI extends JFrame {
private Container contents;
private JButton[][] squares = new JButton[8][8];
private Color colorBlack = Color.BLACK;
private int row = 7;
private int col = 1;
private ImageIcon knight = new ImageIcon("knight.jpg");
public ChessBoardGUI() {
super("GUI GridLayout Manager - (click a valid square to move knight)");
contents = getContentPane();
contents.setLayout(new GridLayout(8,8));
ButtonHandler buttonHandler = new ButtonHandler();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
squares[i][j] = new JButton();
if ((i + j) % 2 != 0) {
squares[i][j].setBackground(colorBlack);
}
contents.add(squares[i][j]);
squares[i][j].addActionListener(buttonHandler);
}
}
squares[row][col].setIcon(knight);
setSize(500, 500);
setResizable(false);
setLocationRelativeTo(null);
setVisible(true);
}
private boolean isValidMove(int i, int j) {
int rowDelta = Math.abs(i - row);
int colDelta = Math.abs(j - col);
if ((rowDelta == 1) && (colDelta == 2)) {
return true;
}
if ((colDelta == 1) && (rowDelta == 2)) {
return true;
}
return false;
}
private void processClick(int i, int j) {
if (isValidMove(i, j) == false) {
return;
}
squares[row][col].setIcon(null);
squares[i][j].setIcon(knight);
row = i;
col = j;
}
private class ButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (source == squares[i][j]) {
processClick(i, j);
return;
}
}
}
}
}
public static void main(String args[]) {
ChessBoardGUI gui = new ChessBoardGUI();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I have a program that creates a chess board GUI, but when I runs my code, the buttons are all white instead of black and white buttons (Just like chess board). Could anyone please tell me where am I doing wrong? Any help is appreciated!
When I runs my program, all I see is a window with white buttons, but there is no black color button.
In my code I added the setOpaque() method but the black color was only at border, so I added this line of code:
squares[i][j].setBorder(null);
Here is the code:
if ((i + j) % 2 != 0) {
squares[i][j].setBackground(colorBlack);
squares[i][j].setBorder(null);
squares[i][j].setOpaque(true);
}

Adding to 2D tabbed JTabbedPane

I am trying to create a 2dimesional JTabbedPane. I found a small example at coderanch to create the JTabbedPane in 2 dimensions. What I would like to do now is add a figure to each tab from an external class after creation of the table. Meaning, I create this table, then place the figures I want inside the table (maybe user does not know needed order beforehand, just knows number of figures to use). But I cannot seem to get the tab to update. I was hoping someone could show me what I am doing incorrectly. Here is a MWE for adding text (instead of a figure).
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTabbedPane;
public class DCTabbed2DPane {
private Dimension screensize;
private JFrame frame;
private JTabbedPane topTabbedPane;
private JTabbedPane[] leftTabbedPane;
private int rows;
private int cols;
private String frameName;
public DCTabbed2DPane(String frameName, int rows, int cols) {
this.frameName = frameName;
this.rows = rows;
this.cols = cols;
init();
}
private void setScreenSize() {
screensize = Toolkit.getDefaultToolkit().getScreenSize();
}
private void setJFrame() {
frame = new JFrame(frameName);
frame.setSize((int) (screensize.getHeight() * .75 * 1.618), (int) (screensize.getHeight() * .75));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private void setJTabbedPane() {
topTabbedPane = new JTabbedPane(JTabbedPane.TOP);
leftTabbedPane = new JTabbedPane[cols];
}
private void setTabs() {
for (int i = 0; i < cols; i++) {
leftTabbedPane[i] = new JTabbedPane(JTabbedPane.LEFT);
for (int j = 0; j < rows; j++) {
leftTabbedPane[i].addTab("Super Layer " + (j + 1), new JLabel("Sector " + (i + 1) + " - " + (j + 1)));
}
topTabbedPane.addTab("Sector " + (i + 1), leftTabbedPane[i]);
}
frame.add(topTabbedPane);
topTabbedPane.setSelectedIndex(-1);
}
private void init() {
setScreenSize();
setJFrame();
setJTabbedPane();
setTabs();
}
public void addCanvasToPane(Integer row, String str) {
leftTabbedPane[row].addTab("", new JLabel(str));
frame.add(topTabbedPane);
frame.revalidate();
frame.repaint();
}
public void showFrame() {
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
int rows = 6;
int cols = 6;
DCTabbed2DPane test = new DCTabbed2DPane("PooperDooper", rows, cols);
for (int j = 0; j < cols; j++) {
test.addCanvasToPane(j, "Name " + j);
}
test.showFrame();
}
}
It's either you want the figure on the tab's navigation, like
leftTabbedPane[i] = new JTabbedPane(JTabbedPane.LEFT);
for (int j = 0; j < rows; j++) {
leftTabbedPane[i].addTab("Super Layer " + (j + 1),new ImageIcon(getClass().getResource("Images/map.png")), new JLabel("Sector " + (i + 1) + " - " + (j + 1)));
}
Or like this one
leftTabbedPane[i] = new JTabbedPane(JTabbedPane.LEFT);
for (int j = 0; j < rows; j++) {
leftTabbedPane[i].addTab("Super Layer " + (j + 1), new MyLabel("Images/Horse.png","").getLabel());
}
where MyLabel is
public class MyLabel {
JLabel label;
String path;
String text;
public MyLabel(String path, String text) {
this.label = new JLabel();
this.path = path;
this.text = text;
}
public void setUpImage(String path) {
this.label.setIcon(new ImageIcon(getClass().getResource(path)));
}
public JLabel getLabel() {
setUpImage(this.path);
return this.label;
}
}

Get buttons already added in a JFrame

I'm developing a simple 15-puzzle game. I added 16 generated numbered buttons to a JFrame and that was the exercise (University).
I'm now trying to go further and make interactions so I need to get all buttons and put them into a 2D vector in order to calculate where user clicks and if and where the cell could "slide", but I don't know how to get them from the Frame.
Here is the generator code:
public void generation(){
int num;
Random rand = new Random();
ArrayList<String> list = new ArrayList<String>();
for(int i = 0; i < this.getTot(); i++)
list.add(""+ i);
while(!list.isEmpty()){
do{
num = rand.nextInt(this.getTot());
} while (!list.contains("" + num));
list.remove("" + num);
if(num == 0){
this.add(new Button(" ");
}
else{
this.add(new Button("" + num);
}
}
}
And here is the constructor:
public Base15(int x, int y){
this.setSize(WIDTH, HEIGHT);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new GridLayout(x, y));
this.x = x;
this.y = y;
this.generation();
this.cells = new Button[x][y];
}
Thank you.
UPDATE: Followed ufis suggestions and had the 2d array done!
for (int row = 0; row < x; row++){
for (int col = 0; col < y; col++){
do{
num = rand.nextInt(this.getTot());
} while (!list.contains("" + num));
list.remove("" + num);
if(num == 0){
cells[row][col] = new Button(" ", sw, label);
this.add(cells[row][col]);
}else{
cells[row][col] = new Button("" + num, sw, label);
this.add(cells[row][col]);
}
}
Thank you all!
Unless I completely misunderstand your question you can do
JFrame theFrame = new JFrame();
// lots of code here to add buttons
Component[] components = theFrame.getComponents();
for (Component component : components) {
if (component instanceof Button) {
// do something
}
}
But it would be better if you store some reference to all your Buttons as you create / add them to the Frame.
EDIT:
I think you should check the way you create your Buttons when you add them to the frame.
When you do
JFrame theFrame = new JFrame();
for (int i = 0; i < 15; i++) {
theFrame.add(new Button());
}
You have no reference to your Buttons. This is why you need to "get the Buttons from the Frame.
If you do something like
JFrame theFrame = new JFrame();
Button[] buttons = new Button[15];
for (int i = 0; i < 15; i++) {
buttons[i] = new Button();
theFrame.add(buttons[i]);
}
You will not have to loop through all the components at a later stage, because you have reference to the buttons in your buttons array. You can of course make that a Button[][] too. But the win here is that you have the reference to the list of buttons at creation time.
public void resetPanel(JFrame form)
{
Component[] components = form.getContentPane().getComponents();
for(Component component : components)
{
if(component instanceof JButton){
JButton button = (JButton) component;
button.setText("?");
}
}
}

Java - why is mask not working?

The idea here is to create a grid of boxes. underneath the black grid is another grid of multi-colored boxes. when you click a box it's mask disappears showing the colored box beneath. You then click a second box if the colors match hurray, if not then the game continues. Here is the code for GuessingGame.java
import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GuessingGame extends Applet{
/**
*
*/
private static final long serialVersionUID = 1L;
private final int START_X = 20;
private final int START_Y = 40;
private final int ROWS = 4;
private final int COLS = 4;
private final int BOX_WIDTH = 20;
private final int BOX_HEIGHT = 20;
//this is used to keep track of boxes that have been matched.
private boolean matchedBoxes[][];
//this is used to keep track of two boxes that have been clicked.
private MaskableBox chosenBoxes[];
private MaskableBox boxes[][];
private Color boxColors[][];
private Button resetButton;
public void init() {
boxes = new MaskableBox[ROWS][COLS];
boxColors = new Color[ROWS][COLS];
resetButton = new Button("Reset Colors");
resetButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
randomizeColors();
buildBoxes();
repaint();
}
});
add(resetButton);
//separate building colors so we can add a button later
//to re-randomize them.
randomizeColors();
buildBoxes();
}
public void paint(Graphics g) {
for (int row =0; row < boxes.length; row ++) {
for (int col = 0; col < boxes[row].length; col++) {
if(boxes[row][col].isClicked()) {
//boxes[row][col].setMaskColor(Color.black);
//boxes[row][col].setMask(!boxes[row][col].isMask());
//boxes[row][col].setClicked(false);
//}
if (!matchedBoxes[row][col]) {
gameLogic(boxes[row][col]);
//boxes[row][col].draw(g);
}
}
}
}
//loop through the boxes and draw them.
for (int row = 0; row < boxes.length; row++) {
for (int col = 0; col < boxes[row].length; col++) {
boxes[row][col].draw(g);
}
}
}
public void gameLogic(MaskableBox box) {
if ((chosenBoxes[0] != null)&&(chosenBoxes[1] != null)) {
chosenBoxes = new MaskableBox[2];
if(chosenBoxes[0].getBackColor() == chosenBoxes[1].getBackColor()) {
for (int i=0; 0 < 2; ++i ) {
for(int row = 0; row < boxes.length; row++) {
for(int col = 0; col < boxes[row].length; col++) {
if( boxes[row][col] == chosenBoxes[i] ) {
System.out.println("boxes [row][col] == chosenBoxes[] at index: " + i );
matchedBoxes[row][col] = true;
break;
}
}
}
}
}else {
chosenBoxes[0].setMask(true);
chosenBoxes[1].setMask(true);
}
}else {
if (chosenBoxes[0] == null) {
chosenBoxes[0] = box;
chosenBoxes[0].setMask(false);
return;
}else{
if (chosenBoxes[1] == null) {
chosenBoxes[1] = box;
chosenBoxes[1].setMask(false);
}
}
}
}
private void removeMouseListeners() {
for(int row = 0; row < boxes.length; row ++) {
for(int col = 0; col < boxes[row].length; col++) {
removeMouseListener(boxes[row][col]);
}
}
}
private void buildBoxes() {
// need to clear any chosen boxes when building new array.
chosenBoxes = new MaskableBox[2];
// create a new matchedBoxes array
matchedBoxes = new boolean [ROWS][COLS];
removeMouseListeners();
for(int row = 0; row < boxes.length; row++) {
for(int col = 0; col < boxes[row].length; col++) {
boxes[row][col] =
new MaskableBox(START_X + col * BOX_WIDTH,
START_Y + row * BOX_HEIGHT,
BOX_WIDTH,
BOX_HEIGHT,
Color.gray,
boxColors[row][col],
true,
true,
this);
addMouseListener(boxes[row][col]);
}
}
}
private void randomizeColors() {
int[] chosenColors = {0,0,0,0,0,0,0,0};
Color[] availableColors = {Color.red, Color.blue, Color.green,
Color.yellow, Color.cyan, Color.magenta, Color.pink, Color.orange };
for(int row = 0; row < boxes.length; row++) {
for (int col = 0; col < boxes[row].length; col++) {
for (;;) {
int rnd = (int) (Math.random() * 8);
if (chosenColors[rnd]< 2) {
chosenColors[rnd]++;
boxColors[row][col] = availableColors[rnd];
break;
}
}
}
}
}
}
here is the second batch of code containing maskablebox
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
public class MaskableBox extends ClickableBox {
private boolean mask;
private Color maskColor;
Container parent;
public MaskableBox(int x, int y, int width, int height, Color borderColor,
Color backColor, boolean drawBorder, boolean mask, Container parent ) {
super(x, y, width, height, borderColor, backColor, drawBorder, parent);
this.parent = parent;
this.mask = mask;
}
public void draw(Graphics g) {
if(mask=false) {
super.draw(g);
// setOldColor(g.getColor());
// g.setColor(maskColor);
// g.fillRect(getX(),getY(),getWidth(), getHeight());
// if(isDrawBorder()) {
// g.setColor(getBorderColor());
// g.drawRect(getX(),getY(),getWidth(),getHeight());
// }
// g.setColor(getOldColor());
}else {
if(mask=true) {
//super.draw(g);
setOldColor(g.getColor());
g.setColor(maskColor);
g.fillRect(getX(),getY(),getWidth(), getHeight());
if(isDrawBorder()) {
g.setColor(getBorderColor());
g.drawRect(getX(),getY(),getWidth(),getHeight());
}
g.setColor(getOldColor());
}
}
}
public boolean isMask() {
return mask;
}
public void setMask(boolean mask) {
this.mask = mask;
}
public Color getMaskColor() {
return maskColor;
}
public void setMaskColor(Color maskColor) {
this.maskColor = maskColor;
}
}
I now get these error messages.
Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
at GuessingGame.gameLogic(GuessingGame.java:74)
at GuessingGame.paint(GuessingGame.java:55)
at java.awt.Container.update(Container.java:1801)
at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
at sun.awt.RepaintArea.paint(RepaintArea.java:216)
at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:306)
at java.awt.Component.dispatchEventImpl(Component.java:4706)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
You are getting a NullPointerException on line 74 of GuessingGame.java in method gameLogic, which corresponds to this line :
if(chosenBoxes[0].getBackColor() == chosenBoxes[1].getBackColor()) {
and the reason you're getting a NullPointerException there is because in the line before it you do:
chosenBoxes = new MaskableBox[2];
which initailizes an array of MaskableBox with 2 references, but the actual MaskableBox objects neeed to be instantiated as well - does that make sense?
Basically the lesson is this: Creating an array of Objects is not the same as creating an array of objects and initializing each one of the elements in the array.
Because at line 73 you do:
chosenBoxes = new MaskableBox[2];
i.e. you create a new MaskableBox array (each element in the new array will be null). The next line you do is:
chosenBoxes[0].getBackColor() == chosenBoxes[1].getBackColor()
chosenBoxes[0] and chosenBoxes[1] are both null since you just created chosenBoxes on the previous line. Remove the call to create a new MaskableBox array and you won't get the NullPointerException.

Categories