Initializing two-dimensional JPanel arrays using a for loop - java

I'm relatively new to java and i'm trying to do an assignment for school. In my assignment i'm supposed to make a GUI program that makes a 8 by 8 red and black colored checkerboard. The only problem (so far) that i'm having is initializing a two-dimensional array of JPanels. i'm getting this error when using eclipse:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
This doesn't give an error until i try to run the code. It says the error is occurring in the body of this for loop:
JPanel[][] panel = new JPanel[7][7];
for (int i = 0; i <= panel.length; i++){
panel[i][0] = new JPanel();
panel[i][1] = new JPanel();
panel[i][2] = new JPanel();
panel[i][3] = new JPanel();
panel[i][4] = new JPanel();
panel[i][5] = new JPanel();
panel[i][6] = new JPanel();
panel[i][7] = new JPanel();
}
This does work if i don't use a for loop but i really don't want to put in 64 different statements do do this. I double checked and the panel.length does give the value 7 (which is what i wanted) and did not work even when i physically put in 7. I don't have any syntax error is my code, but i still get the error. Is there some other way i should go about doing this? Thanks in advance. Remember i'm new to this.

"make a GUI program that makes a 8 by 8 red and black colored checkerboard. The only problem (so far) that i'm having is initializing a two-dimensional array of JPanels.".
If all you need to do is make the board, with no other conditions, why not just use a GridLayout
JPanel mainPanel = new JPanel(new GridLayout(8, 8));
for (int i = 0; i < 64; i++){
JPanel panel = new JPanel();
// alternate background colors with a predefined boolean and an if
mainPanel.add(panel);
}

Three things:
A checkboard is 8×8, so you really want panel.length to be 8, no?
A standard for loop uses < for the test, not <=.
If you use two nested loops, you don't need to repeat new JPanel() 8 times.
Result:
JPanel[][] panel = new JPanel[8][8];
for (int i = 0; i < panel.length; i++) {
for (int j = 0; j < panel[i].length; j++) {
panel[i][j] = new JPanel();
}
}

Related

JFrame window resizing on every compile. Different results every time

Erm, I'm not too sure what's happening... For the life of me I didn't even try and debug after running the application several times in a row from the IDE. I decided to come straight over here and explain what I consider to be odd.
I'm trying to create a chessboard with tan and beige squares, I have a JFrame window set to 1024x1024 in size, so a square. I also am using a gridLayout of 8x8.
Every time I run the application I might get a grid of say 6x8, the next run a 5 x8, or next a 7x7.
Not sure what's going on... Any help would be sweet!
public class ChessBoard extends JFrame{
private final JFrame board = new JFrame();
private final JButton button = new JButton();
private final GridLayout grid = new GridLayout(8, 8);
public ChessBoard(){
board.setSize(1024, 1024);
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board.setVisible(true);
board.setLayout(grid);
AddGridColors();
}
private void AddGridColors(){
Color tanColor = new Color(210, 180, 140);
Color beigeColor = new Color(245, 245, 220);
JPanel[] panelArray = new JPanel[63];
int panelArrayIndex;
for(panelArrayIndex = 0; panelArrayIndex < 63; ++panelArrayIndex){
panelArray[panelArrayIndex] = new JPanel();
if(panelArrayIndex == 0){
panelArray[panelArrayIndex].setBackground(tanColor);//tan
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
if(panelArrayIndex > 0){
if(panelArrayIndex % 8 == 0){
panelArray[panelArrayIndex].setBackground(beigeColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
if(panelArray[panelArrayIndex-1].getBackground().equals(tanColor)){
panelArray[panelArrayIndex].setBackground(beigeColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}else{
panelArray[panelArrayIndex].setBackground(tanColor);
panelArray[panelArrayIndex].add(new JLabel("square"+panelArrayIndex));
board.add(panelArray[panelArrayIndex]);
}
}
}
}
Is this normal, am I missing something incredibly obvious?
From my above comment:
Could you try moving the call to AddGridColors(); right before setSize(1024, 1024);
This could be because you're calling setVisible(true); before you've added all your elements to the JFrame and thus, causing issues like this one.
setVisible(true); should be the last line on your program.
Btw follow the Java naming conventions
firstWordLowerCaseVariable
firstWordLowerCaseMethod()
FirstWordUpperCaseClass
ALL_WORDS_UPPER_CASE_CONSTANT
I said this:
Also, shouldn't your for-loop be from 0 to 64 instead of 0 to 63?
Because your for-loop is going from 0-63 (without including 63)
for(panelArrayIndex = 0; panelArrayIndex < 63; ++panelArrayIndex){
Should be either:
for(panelArrayIndex = 0; panelArrayIndex < 64; ++panelArrayIndex){
Or
for(panelArrayIndex = 0; panelArrayIndex <= 63; ++panelArrayIndex){
But the same should go for your panel's array (There are 63 elements, not 64):
JPanel[] panelArray = new JPanel[63];
Should be:
JPanel[] panelArray = new JPanel[64];

Declare multiplie swing elements at once

I am working on a little game, a Java project for IT-classes.
To add/declare(???) Java swing elements I've used this type of writing:
JLabel A = new JLabel();
JLabel B = new JLabel();
//More JLabels...
JButton A = new JButton();
JButton B = new JButton();
//More JButtons...
That the code does not become longer and (more) confusing, I continued with this type of writing:
JLabel A = new JLabel(), B = new JLabel()/*More JLabels...*/;
JButton A = new JButton(), B = new JButton()/*More JButton...*/;
/*Generaly more comments everywhere over the code for my teacher (and me)
*and more for a better overview.
*/
My question is:
Is there a shorter way to add/declare(???) multiple Java swing elements at once?
//like this
JLabel A, B, C, D, E, F = new JLabel();
//or
new JLabel[A, B, C, D, E, F];//PLS don't ask what I'm doing in this line xD
or may is there already a semilar question in Stackoverflow that I've not found?
Edit
This question may already have an answer here: Initializing multiple
variables to the same value in Java 6 answers
Here the Link to the question
Your question has been identified as a possible duplicate of another
question. If the answers there do not address your problem, please
edit to explain in detail the parts of your question that are unique.
Not worked with Jbuttons and JLabels.
If you are using Java 8 you can use :
List<String> labels = ....;
Stream<Button> stream = labels.stream().map(Button::new);
List<Button> buttons = stream.collect(Collectors.toList());
From the book Java se 8 for the really impatient
Then you can use :
JPanel p = new JPanel();
buttons.forEach((t) -> p.add(t));//add your buttons to your panel
It depends, if all your objects are JLabel or the same object type, you could try:
An array of JLabel like:
JLabel[] labels = new JLabel[size of your array];
Then access it after inside a for loop:
for (int i = 0; i < labels.length; i++) {
labels[i] = new JLabel("I'm label: " + i);
}
A List of labels:
ArrayList <JLabel> labelsList = new ArrayList <JLabel>();
Then you could:
for (int i = 0; i < 10; i++) { //I take 10 as an arbitrary number just to do it in a loop, it could be inside a loop or not
labelsList.add(new JLabel("I'm label-list: " + i));
}
And later you could add them like:
pane.add(labels[i]); //Array
pane.add(labelsList.get(i)); //List
The above code should be inside a loop or change i for the explicit index of the element to be added.
If you want to do the same thing (or a similar thing) many times in a program, the answer is to use a loop of some kind. Here, you could declare an array (or List) of JButton elements, and loop over it to initialize its elements:
final int NUM_BUTTONS = 6;
JButton[] buttons = new JButton[NUM_BUTTONS];
for (int i = 0; i < NUM_BUTTONS; i++) {
buttons[i] = new JButton();
}
// refer to A as buttons[0], C as buttons[2], etc
You can make variables equal to each other after declaring them.
String one, two, three;
one = two = three = "";
So, I think you could do
JLabel A,B,C,D,E,F;
A = B = C = D = E = F = new JLabel();

For loop to create button array not displaying properly in JPanel

So i'm creating an array of buttons that is supposed to display and 8,8 grid, instead it displays very small buttons spreading across the window (31 buttons in a row for two rows then two more buttons on the third). If I replace:
gamePanel1.add(buttons[a][b]);
with:
frame.add(buttons[a][b]);
... it display correctly but when initialising the array, I have to resize the window to see the buttons as it does not fit to contents.
Here is the code to create the buttons:
contentPane.setLayout(new BorderLayout());
JPanel gamePanel1 = new JPanel();
buttons = new JButton[boardsize][boardsize];
mineBoard = new int[9][9];
for (int a = 0; a < boardsize; a++)
for (int b = 0; b < boardsize; b++) {
buttons[a][b] = new JButton("");
buttons[a][b].setBounds(30+gridsize*a,30+gridsize*b,gridsize,gridsize);
gamePanel1.add(buttons[a][b]);
buttons[a][b].addMouseListener(new MouseListener(a,b));
setx(a);
sety(b);
settried(false);
setmine(false);
}
contentPane.add(gamePanel1, BorderLayout.CENTER);
Can anyone tell me how I might fix this or show me how with this code I may use a different layout - i tried grid layout for the buttons but could not get it working at all.
First create a Panel as:
JPanel panel=new JPanel();
Then set the layout as
panel.setLayout(new GridLayout(8,8));
Then using a for loop create and add the buttons and the buttons will be displayed in eight by eight grid. Thanks.

Java Button Action Command

I'm creating a simple Minesweeper game in Java. Size 9x9.
I create an array of JPanels and an array of buttons; I add each button to its respective JPanel. then i add the JPanels to the JFrame.
How do i distinguish between each button on the action event?
Here's some of my code:
int gridx = 9;
int gridy = 9;
JButton[] buttons = new JButton[gridx*gridy];
JPanel[] jpanels = new JPanel[gridx*gridy];
public Minesweeper(){
super("Minesweeper");
setLayout(new GridLayout(9,9));
JPanel panel = new JPanel();
int i = 0;
for(i = 0; i<gridx*gridy; i++){
jpanels[i] = new JPanel();
buttons[i] = new JButton();
buttons[i].addActionListener(buttonEvent);
jpanels[i].setLayout(new GridLayout(1,1));
jpanels[i].add(buttons[i]);
add(jpanels[i]);
}
//buttons[67].setEnabled(false);
setSize(300,300);
setVisible(true);
}
The only way i can think about doing this is adding text to the button like so:
buttons[i] = new JButton(i);
Then calling getActionCommand() but i dont want text to show up on the button. Any other ideas?
You can use AbstractButton#setActionCommand.
In your loop:
buttons[i].setActionCommand(i+"");
Then you'll get i back when you use getActionCommand
Note I did mention in a comment on another answer that I would create a new class Mine which extends JButton which I believe to be a better and more complete solution. This however gets the job done rather quickly.

JScrollPane not scrolling when a JPanel is added

I was hoping someone would be able to help. This seems like it should be a simple problem but for the life of me I can't work it out.
Problem: I am creating a JPanel that is made up of panels containing 5 labels each with ImageIcons. [sounds confusing]
I am then adding this panel to a JScrollPane. But when it is displayed the images are showing and correctly placed but I am unable to scroll down to see the panels that are off the screen.
here is a screenshot: http://img841.imageshack.us/img841/36/screenshot20120510at160.png
Here is the snippet of code I am using to populate the panels and add the JScrollPane.
private void setSeriesViewContainer(){
container = new BackgroundPanel(backGround, BackgroundPanel.TILED);
//container.setPreferredSize(new Dimension(650,500));
container.setLayout(new BoxLayout(container, BoxLayout.PAGE_AXIS));
FlowLayout flowLayout = new FlowLayout();
JPanel[] jp = new BackgroundPanel[10];
for (int i = 0; i < jp.length; i++) {
jp[i] = new BackgroundPanel(backGround, BackgroundPanel.TILED);
jp[i].setLayout(flowLayout);
for (int j = 0; j < 10; j++) {
jp[i].add(new JLabel(new ImageIcon(getClass().getResource("/placeHolder.png"))));
}
}
for (int i = 0; i < jp.length; i++) {
container.add(jp[i]);
}
public void init(){
seriesViewContainer = new javax.swing.JScrollPane(container);
seriesViewContainer.setBorder(null);
seriesViewContainer.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
seriesViewContainer.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
seriesViewContainer.setPreferredSize(new java.awt.Dimension(700, 300));}
I have searched around for the solution but have not come up with one as yet.
container.setPreferredSize(new Dimension(x,y)); the dimensions of container should be larger than the dimensions of the scrollpane.
from what I've read setPreferredSize() is not a good thing to use though. The problem is probably the LayoutManager for container or jp.
same problem here: Java Swing: JScrollPane not working
Have you tried to call revalidate() to the JScrollPane and/or container after each add ?

Categories