2

The first image shows what the GUI looks like when I just start it, the second shows what happens when I click around the board. The chess pieces show up at the top row after I click a piece and then click on a button on the top row. What is happening here?!

The code is below; this class is where I have most of my code. The rest of the classes are just loading images at this point. The Board constructor is called in the main to build the GUI.

public class  BoardPanel extends JPanel {

public BoardPanel() {     

    createBoard();

}

private void createBoard(){

    setLayout(new GridLayout(10, 10));

    // Makes a 10 x 10 grid of black and white colors
    for (int i = 0; i<10; i++){
        for (int j = 0; j<10; j++){
            square[i][j] = new JButton();
            square[i][j].setRolloverEnabled(false);

            if ((i+j)%2 == 0)
                square[i][j].setBackground(Color.WHITE);

            else 
                square[i][j].setBackground(Color.LIGHT_GRAY);

            add(square[i][j]);
        }
    }                      
    addLabels();
    //Colors the corner squares
    square[0][0].setBackground(new Color(155, 234, 242, 100));
    square[0][9].setBackground(new Color(155, 234, 242, 100));
    square[9][0].setBackground(new Color(155, 234, 242, 100));
    square[9][9].setBackground(new Color(155, 234, 242, 100));                      
}

private void addLabels(){
    //Adds labels to the ranks
    for  (int i =1 ; i< 9; i++){
        square[i][0].setBackground(new Color(155, 234, 242, 100));            
        square[i][0].setText(rank[8-i]);
        square[i][0].setHorizontalTextPosition(SwingConstants.RIGHT);

        square[i][9].setBackground(new Color(155, 234, 242, 100));                          
        square[i][9].setText(rank[8-i]);
        square[i][9].setHorizontalTextPosition(SwingConstants.LEFT);

}
    //Adds labels to the files
    for (int j = 1; j<9;j++){
        square[0][j].setBackground(new Color(155, 234, 242, 100));
        square[0][j].setText(file[j-1]);  
        square[0][j].setVerticalTextPosition(SwingConstants.BOTTOM);

        square[9][j].setBackground(new Color(155, 234, 242, 100));            
        square[9][j].setText(file[j-1]);
        square[9][j].setVerticalTextPosition(SwingConstants.TOP);
    }
JButton square[][] = new JButton[10][10];
String[] rank = {"1","2","3","4","5","6","7","8"};
String[] file = {"a","b","c","d","e","f","g","h"};
}
}

The main class

public class Board {


public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.add(new BoardPanel());
    frame.setVisible(true);
    frame.setSize(900, 700);      

    }

}
Aeleon
  • 169
  • 9
  • Have you run your code step-by-step under debugger? – PM 77-1 Jun 28 '15 at 01:11
  • 5
    You don't show any event code... event code is clearly necessary to debug the issue. – Arhowk Jun 28 '15 at 01:13
  • 3
    How can we guess what is wrong based on unrunnable snippets? First you must work to try to isolate your problem, and then if still stuck, post the smallest functioning code that reproduces your problem, an [sscce](http://sscce.org) or a [minimal example program/mcve](http://stackoverflow.com/help/mcve). And is your program doing any custom painting/drawing anywhere? – Hovercraft Full Of Eels Jun 28 '15 at 01:27
  • By event code, are you talking about actionlisteners and stuff? Because I haven't implemented those yet. What I posted is pretty much all I have. As for the smallest code that produces the problem, that would be the createBoard() method. The problem is still produced after I comment out setup() in the constructor. It's just that this time, there are no pieces that appear at the top of the board since they haven't been created yet. – Aeleon Jun 28 '15 at 01:30
  • 2
    Again consider creating and posting an [sscce](http://sscce.org) or a [minimal example program/mcve](http://stackoverflow.com/help/mcve) where you condense your code into the smallest bit that still compiles and runs, has no outside dependencies (such as need to link to a database or images), has no extra code that's not relevant to your problem, but still demonstrates your problem. Otherwise we risk playing a long and painful game of guess what is wrong with code not shown. – Hovercraft Full Of Eels Jun 28 '15 at 01:41
  • The code should be able to run now. My problem is the corner squares, how do I prevent the text from appearing there? – Aeleon Jun 28 '15 at 01:56
  • The class attributes, square, rank, and file are all at the bottom of the first snippet of code. Also I don't see which images are still present in the code. I don't even have an ImageIcon variable. Could you be a bit more specific? – Aeleon Jun 28 '15 at 02:28
  • My IDE wasn't picking up on the arrays at the bottom since your code appears to be missing a closing brace that closes out the addLabels method. Let me recheck, mean time, please fix your code while I test mine. – Hovercraft Full Of Eels Jun 28 '15 at 02:35
  • I see your problem now: it is because you are using Colors with an alpha component set, something that requires special handling with Swing. 1+ to your question for the changes you've made. I am not that skilled at Swing graphics to come up with a ready solution other than to suggest avoiding use of colors with alpha, but search on this site on this issue and you'll find some similar questions. – Hovercraft Full Of Eels Jun 28 '15 at 02:43
  • I'll take a look around I guess, it should be easy to find since I know its a problem with Color. Thankyou – Aeleon Jun 28 '15 at 02:48
  • @Aeleon I just tried running your code, and there are no colors at all. – xrisk Jun 28 '15 at 02:58
  • @Aeleon have a look at how your code looks on my computer: http://imgur.com/WDteDIG certainly not what you wanted right? – xrisk Jun 28 '15 at 03:06
  • 1
    Probably unrelated to this problem, but you should be doing this: http://stackoverflow.com/questions/15302085/why-to-use-swingutilities-invokelater-in-main-method/ – Kevin Krumwiede Jun 28 '15 at 03:10
  • the main method is automatically created by my IDE, I haven't really touched it. But thanks for this. I didn't think I'd to worry about deadlocks until I actually put threads in my code. – Aeleon Jun 28 '15 at 03:13

1 Answers1

6

Your problem is with the button thinking that it is fully opaque when it is in fact not opaque. As per Kleopatra in this answer, you must make the button non-opaque and take over the painting mechanisms

        square[i][j] = new JButton() {
           @Override  // !! add this:
           protected void paintComponent(Graphics g) {
              if (!isOpaque() && getBackground().getAlpha() < 255) {
                 g.setColor(getBackground());
                 g.fillRect(0, 0, getWidth(), getHeight());
             }
             super.paintComponent(g);
           }
        };
        square[i][j].setRolloverEnabled(false);
        square[i][j].setOpaque(false); // !! and also add this *******

As a side note, I wouldn't be using JButtons for this type of problem, but rather I'd be using JPanels, and would place my chess pieces as ImageIcons displayed in JLabels, labels that are added to or removed from the appropriate chess-board squares.


A board without buttons and without use of alpha colors:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class Board2 extends JPanel {

   private static final int SIDE_LEN = 80;
   private static final Dimension SQUARE_SZ = new Dimension(SIDE_LEN, SIDE_LEN);
   private static final Color EDGE_COLOR = new Color(165, 245, 250);
   private static final Color DARK_SQR_COLOR = Color.LIGHT_GRAY;
   private static final Color LIGHT_SQR_COLOR = Color.WHITE;
   private JPanel[][] chessSquares = new JPanel[8][8]; 

   public Board2() {
      setLayout(new GridLayout(10, 10)); // sorry for magic numbers
      for (int i = 0; i < 10; i++) {
         for (int j = 0; j < 10; j++) {
            if ((i == 0 || i == 9) && (j == 0 || j == 9)) {
               add(createEdgePanel(""));
            } else if (i == 0 || i == 9) {
               String text = String.valueOf((char) (j + 'a' - 1));
               add(createEdgePanel(text));
            } else if (j == 0 || j == 9) {
               String text = String.valueOf(8 - i + 1);
               add(createEdgePanel(text));
            } else {
               JPanel panel = createSquare(i, j);
               add(panel);
            }
         }
      }
   }

   private JPanel createSquare(int i, int j) {
      JPanel panel = new JPanel(new GridBagLayout());
      Color c = (i % 2 == j % 2) ? LIGHT_SQR_COLOR : DARK_SQR_COLOR;
      panel.setBackground(c);
      panel.setPreferredSize(SQUARE_SZ);
      panel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      return panel;
   }

   private JPanel createEdgePanel(String text) {
      JLabel label = new JLabel(text, SwingConstants.CENTER);
      JPanel panel = new JPanel(new GridBagLayout());
      panel.add(label);
      panel.setBackground(EDGE_COLOR);
      panel.setPreferredSize(SQUARE_SZ);
      panel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      return panel;
   }

   private static void createAndShowGui() {
      Board2 mainPanel = new Board2();

      JFrame frame = new JFrame("Board2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

Which on my system looks like:

enter image description here

Now with some pieces added:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class Board2 extends JPanel {
   private static final int SIDE_LEN = 80;
   private static final Dimension SQUARE_SZ = new Dimension(SIDE_LEN, SIDE_LEN);
   private static final String SPRITE_PATH = "https://i.stack.imgur.com/memI0.png";
   private static final int SPRITE_ROWS = 2;
   private static final int SPRITE_COLS = 6;
   private static final Color EDGE_COLOR = new Color(165, 245, 250);
   private static final Color DARK_SQR_COLOR = Color.LIGHT_GRAY;
   private static final Color LIGHT_SQR_COLOR = Color.WHITE;
   private static final int ROWS = 8;
   private JLabel[][] chessSquares = new JLabel[ROWS][ROWS]; 
   private BufferedImage bigImage;
   private List<Icon> icons = new ArrayList<>();

   public Board2() throws IOException {
      URL imgUrl = new URL(SPRITE_PATH);
      bigImage = ImageIO.read(imgUrl);
      int w = bigImage.getWidth() / SPRITE_COLS;
      int h = bigImage.getHeight() / SPRITE_ROWS;
      for (int i = 0; i < SPRITE_ROWS; i++) {
         for (int j = 0; j < SPRITE_COLS; j++) {
            int x = (j * bigImage.getWidth()) / SPRITE_COLS;
            int y = (i * bigImage.getHeight()) / SPRITE_ROWS;
            BufferedImage spriteImg = bigImage.getSubimage(x, y, w, h);
            Icon spriteIcon = new ImageIcon(spriteImg);
            icons.add(spriteIcon);
         }
      }

      for (int i = 0; i < chessSquares.length; i++) {
         for (int j = 0; j < chessSquares[i].length; j++) {
            chessSquares[i][j] = new JLabel();
         }
      }

      setLayout(new GridLayout(ROWS + 2, ROWS + 2)); // sorry for magic numbers
      for (int i = 0; i < 10; i++) {
         for (int j = 0; j < 10; j++) {
            if ((i == 0 || i == ROWS + 1) && (j == 0 || j == ROWS + 1)) {
               add(createEdgePanel(""));
            } else if (i == 0 || i == ROWS + 1) {
               String text = String.valueOf((char) (j + 'a' - 1));
               add(createEdgePanel(text));
            } else if (j == 0 || j == ROWS + 1) {
               String text = String.valueOf(ROWS - i + 1);
               add(createEdgePanel(text));
            } else {
               JPanel panel = createSquare(i, j);
               panel.add(chessSquares[i - 1][j - 1]);
               add(panel);
            }
         }
      }

      setPieces(0, 0, 2); // rooks
      setPieces(1, 0, 3); // knights
      setPieces(2, 0, 4); // bishops

      // kings and queens
      chessSquares[0][3].setIcon(icons.get(1));
      chessSquares[7][3].setIcon(icons.get(6 + 1));
      chessSquares[0][4].setIcon(icons.get(0));
      chessSquares[7][4].setIcon(icons.get(6 + 0));

      // pawns
      for (int i = 0; i < ROWS / 2; i++) {
         setPieces(i, 1, 5);
      }

   }

   private void setPieces(int colPos, int rowPos, int pieceIndex) {
      chessSquares[rowPos][colPos].setIcon(icons.get(pieceIndex));
      chessSquares[rowPos][ROWS - 1 - colPos].setIcon(icons.get(pieceIndex));
      chessSquares[ROWS - 1 - rowPos][colPos].setIcon(icons.get(6 + pieceIndex));
      chessSquares[ROWS - 1 - rowPos][ROWS - 1 - colPos].setIcon(icons
            .get(6 + pieceIndex));
   }

   private void setPiece(int colPos, int pieceIndex) {
      chessSquares[0][colPos].setIcon(icons.get(pieceIndex));
      chessSquares[ROWS - 1][ROWS - 1 - colPos].setIcon(icons.get(6 + pieceIndex));
   }

   private JPanel createSquare(int i, int j) {
      JPanel panel = new JPanel(new GridBagLayout());
      Color c = (i % 2 == j % 2) ? LIGHT_SQR_COLOR : DARK_SQR_COLOR;
      panel.setBackground(c);
      panel.setPreferredSize(SQUARE_SZ);
      panel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      return panel;
   }

   private JPanel createEdgePanel(String text) {
      JLabel label = new JLabel(text, SwingConstants.CENTER);
      JPanel panel = new JPanel(new GridBagLayout());
      panel.add(label);
      panel.setBackground(EDGE_COLOR);
      panel.setPreferredSize(SQUARE_SZ);
      panel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
      return panel;
   }

   private static void createAndShowGui() {
      Board2 mainPanel = null;
      try {
         mainPanel = new Board2();
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

      JFrame frame = new JFrame("Board2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

enter image description here

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Passer-by running your code… is this how it’s supposed to look? http://imgur.com/WDteDIG – xrisk Jun 28 '15 at 03:02
  • @RishavKundu: no, it's not. The buttons themselves should be colored. – Hovercraft Full Of Eels Jun 28 '15 at 03:03
  • 1
    Is this supposed to be platform-dependent? – xrisk Jun 28 '15 at 03:04
  • @RishavKundu: no it should not be platform or L&F dependent, but per your code, it appears that it is. What happens when you run the original poster's original code. – Hovercraft Full Of Eels Jun 28 '15 at 03:06
  • In reply to your comment in my original post: the color is still there in the image you posted,its just underneath the buttons. As for how this looks, did you change the code? That's how my gui looks if I simply use the grid layout on the frame. However, if I use the layout on a panel and then put that panel on a frame, the gui should look like the images in my question. – Aeleon Jun 28 '15 at 03:08
  • are you running both the Board and the BoardPanel class or just the BoardPanel class? – Aeleon Jun 28 '15 at 03:17
  • @Aeleon I am running both of them. And you should notify me by a `@Rishav` hehe. – xrisk Jun 28 '15 at 03:20
  • @RishavKundu I didn't know the commenting system had such a feature. Anyways, when I run my code, I get what you see in the images I posted. However, I when I was writing the code for this, I did run into what you are showing with all the buttons showing up like that. The reason I found for that was that I was creating buttons using GridLayout on a JFrame. I fixed that by creating buttons on a JPanel instead. I implemented that in the code I've posted here. – Aeleon Jun 28 '15 at 03:25
  • @Aeleon some L&Fs support colored buttons, some don’t. Here read this http://stackoverflow.com/questions/22109821/java-how-to-fill-a-windows-lf-button-with-color-instead-of-just-the-border You should probably set it to Nimbus or Metal to make it cross-platform. And sorry for spamming your answer Hovercraft – xrisk Jun 28 '15 at 03:25
  • @RishavKundu: no problem, and in fact I appreciate it as solutions **should** be platform and L&F independent. Could I trouble you to run my latest code, one that does not use JButtons? – Hovercraft Full Of Eels Jun 28 '15 at 03:32