I used this procedure in a program to make an array of JButton
s. The JButtons
do show up in the frame, but the ImageIcon
is not put into the buttons. The picture is at the same directory as the program. What is the problem? (space is my frame)
static void BasicSetup() {
int count1 = 0;
int count2 = 0;
ImageIcon cell = new ImageIcon("cell.png");
for (int y = 0; y < 16; y++) {
count1 = count1 + 1;
count2 = 0;
for (int x = 0; x < 16; x++) {
count2 = count2 + 1;
field[y][x] = new JButton();
field[y][x].setIcon(cell);
constraints.gridx = count1;
constraints.gridy = count2;
constraints.weightx = 1;
jpanel.add(field[y][x], constraints);
}
}
space.add(jpanel);
}
From what I see, your error comes due to the way you're reading the image.
In this case I used an image from this question.
When you pack your app as a JAR file, you'll need to access the images as resources anyway, so, it's better to start accessing them that way right now. In this moment your code is loading the image directly from your filesystem instead of as a resource. You can change it by calling ImageIO.read()
method (The linked one is for an URL which I'm using due to linking to an image of the question linked above, but you can read by File
, InputStream
or ImageInputStream
too.
For example:
img = ImageIO.read(getClass().getResource("L5DGx.png"));
As you're using the same image for each of the buttons (and probably the same size for each button), I recommend you to use GridLayout
instead of GridBagLayout
.
You can copy-paste this code without modifications, this is called a Minimal, Complete and Verifiable Example (MCVE) or a Short, Self Contained, Correct Example (SSCCE) and next time you should post one similar, so we don't have to write the imports or deduce that field
is a JButton
array instead of another JComponent
(for example a JTextField
that might better fit the name of field
)
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageIconArray {
private JButton[][] buttons = new JButton[16][16];
private JPanel pane;
private JFrame frame;
private GridBagConstraints constraints = new GridBagConstraints();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ImageIconArray().createAndShowGui();
}
});
}
public void createAndShowGui() {
BufferedImage img = null;
URL url;
try {
url = new URL("https://i.sstatic.net/L5DGx.png");
img = ImageIO.read(url);
} catch (IOException ioe) {
ioe.printStackTrace();
}
Icon cell = new ImageIcon(img);
frame = new JFrame("Example");
pane = new JPanel();
pane.setLayout(new GridLayout(16, 16));
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
buttons[i][j] = new JButton();
buttons[i][j].setIcon(cell);
constraints.gridx = i;
constraints.gridy = j;
constraints.weightx = 1;
pane.add(buttons[i][j], constraints);
}
}
frame.add(pane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here's an output image of what I got when running the above code:
You're making a static
method for the creation of the GUI, I suggest you to instead create an instance of your class and call the method that way (w/o the static
modifier).
From the code shown, I deduce that you're not placing your program on the Event Dispatch Thread (EDT), this might cause you problems due to Threading issues, you can fix it the way I did in the main
method, calling SwingUtilities#invokeLater()
method.
Your variable naming is confuse, you call space
to a JFrame
, if I were you I would call it frame
or spaceFrame
. field
I would call field
to a JTextField
not a JButton
array, I would call that JButton
array as buttons
(in plural as it refers to many of them) or fieldButtons
.
Your for
loops are (in my opinion) inverted, I would start from x
and then continue to y
(or do as everyone does and use i
, j
, k
for counter variables in simple loops, or make them have a more descriptive name)
You're using count1
and count2
variables, which are not necessary, you can have your constraints.gridx = i;
and constraints.gridy = j;
(If you prefer using i
and j
as your counter variables in your for
loops as recommended above) or constraints.gridx = y;
and constraints.gridy = x;
(if you decide to ignore my tip #4) or constraints.gridx = x;
and constraints.gridy = y;
(if you decide to take my tip #4)