简体   繁体   中英

ImageIcon cannot be set to JButton?

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.stack.imgur.com/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:

在此处输入图片说明


Additional Tips

  1. 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).

  2. 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.

  3. 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 .

  4. 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)

  5. 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM