【问题标题】:JButton will not change update image when using .setIcon(ICON);使用 .setIcon(ICON) 时,JButton 不会更改更新图像;
【发布时间】:2014-01-20 23:10:36
【问题描述】:

我已经检查了this 重复问题和其他类似问题,但没有帮助。我试图在单击按钮时将 png 添加到按钮。该程序是一个可变大小的学校井字游戏。

现在我有:

private ImageIcon X_MARK = new ImageIcon("x.png");
private ImageIcon O_MARK = new ImageIcon("o.gif");
private JButton[][] cells;

...

    cells = new JButton[size][size];
    JPanel board = new JPanel(new GridLayout(size, size));
    board.setBorder(new LineBorder(Color.BLACK, 1));

    ButtonListener listener = new ButtonListener();

    for (int i = 0; i < size; i++)
        for (int j = 0; j < size; j++) {
            cells[i][j] = new JButton();
            cells[i][j].addActionListener(listener);
            board.add(cells[i][j]);
        }
    JFrame ttt = new JFrame();
    ttt.add(board);
    ttt.setTitle("Show GUI Components");
    ttt.setSize(60*size, 60*size);
    ttt.setLocation(0, 0);
    ttt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    ttt.setVisible(true);

...

class ButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {

        int i, j;

        for (i = 0; i < size; i++)
            for (j = 0; j < size; j++)
                if (e.getSource() == cells[i][j]) {
                    if ((i + j) % 2 == 0) {
                        cells[i][j].setBackground(Color.GREEN);
                        cells[i][j].setIcon(X_MARK);
                    } else {
                        cells[i][j].setBackground(Color.CYAN);
                        cells[i][j].setIcon(O_MARK);
                    }
                }

    }
}

这就是我认为的所有相关代码。我正在使用 Eclipse,我在项目的 src 文件夹和 bin 文件夹中有 x.png 和 o.png 。我还尝试了一些我在 SO 和 google 搜索中看到的变体,例如new ImageIcon("C:/Users/BigBoy/workspace_1/EventDriven/src/x.png");new ImageIcon("src/x.png");,以及其他一些涉及getClass().getResource 的变体。我不知道还能尝试什么。我知道我过去曾这样做过,并没有遇到这么多麻烦。

我添加 .setBackground(Color.GREEN); 只是为了确保我的点击注册正确,对我来说,问题似乎与 ImageIcon 的声明/初始化有关。

注意:现在我的按钮监听器只是制作棋盘图案,在我弄清楚这个图标问题后,我将开始实际放置每个玩家的标记。

【问题讨论】:

  • 1) 我认为最相关的代码在您的 ButtonListener 类中。你怎么不发这个? 2)你还做了什么调试?你能显示任何图像吗?
  • 你知道,如果你遇到这样的问题,你应该首先尝试在小型测试程序中解决它们,而不是在你的作业中。我首先要确保创建一个非常小的程序,在 JOptionPane 中显示一个 ImageIcon,仅此而已。
  • 另外,您应该提供您的包结构的图像,以及您的图像与该结构相关的位置。这是关键。如果不是图像,则有 jar 命令可以为我们提供几乎相同的东西(如果程序在 jar 中)。
  • 这对我来说绝对完美,你确定图像在它们应该在的位置吗?
  • “我已经检查了这个重复的问题,但它没有帮助。” 我不明白为什么你没有注意到重复的问题有一个正在尝试的答案通过 URL 加载图像,而您的代码试图加载它们,就好像它们是 File。对于这种类型的embedded-resource,图标将不能用作File

标签: java swing jpanel jbutton embedded-resource


【解决方案1】:

您需要了解您想要使用的资源。它们相对于类文件定位。如果图像带有类文件,则

  • 将您的图片作为资源获取
  • 从图像创建一个 ImageIcon。

例如:

package whateverpackeyouareusing;

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.JOptionPane;


public class DefaultFoo {
   public static void main(String[] args) throws IOException {
      String resource = "x.png";
      URL url = Class.class.getResource(resource);
      BufferedImage img = ImageIO.read(url);
      Icon icon = new ImageIcon(img);
      JOptionPane.showMessageDialog(null, icon);
   }
}

编辑:Andrew Thompson 的一个更好的例子:

package some.package;

import java.awt.Image;
import java.io.IOException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;


public class PlayWithImages {
   public static final String X_RESOURCE = "x.png";
   private Icon xIcon;

   public PlayWithImages() throws IOException {
      URL xImgUrl = getClass().getResource(X_RESOURCE);
      Image xImg = ImageIO.read(xImgUrl);
      xIcon = new ImageIcon(xImg);
   }

   public Icon getXIcon() {
      return xIcon;
   }

   public static void main(String[] args) {
      try {
         PlayWithImages playWithImages = new PlayWithImages();
         Icon xIcon = playWithImages.getXIcon();
         JOptionPane.showMessageDialog(null, xIcon);
      } catch (IOException e) {
         e.printStackTrace();
      }

   }
}

【讨论】:

  • URL url = Class.class.getResource(resource); AFAIR 我们可以在static 方法中获得的类加载器,如main 不是上下文类加载器。只有上下文类加载器在类路径上会有x.png。出于这个原因,我总是尝试以非静态方法加载资源,然后使用this.getClass().getResource(..) 加载应用程序资源..
  • 是的。第二个是我的处理方式。 :)
  • 好吧,我很生气。我只用一个按钮制作了一个较小的测试程序,并尝试在其上设置图标。不能在 Eclipse 中工作,但在 JGrasp 中工作得很好。在 JGrasp 中尝试了我的原始程序,它可以工作!原来 GIF 需要在 Package 文件夹中,而不是 SRC 或 BIN 文件夹中。所以在我的情况下,我不得不将 GIF 放到 C:\Users\BigBoy\workspace_1\EventDriven
  • 您的回答似乎有点超出我的想象,使用 URL。我确信这是一个很好的答案,但我需要做的就是将我的图像文件放在 Project 文件夹中。
  • @ChrisWilson4:您所做的是让您的代码在放入 Jar 时无法使用。玩弄资源并学习使用它们,否则后果自负。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多