【问题标题】:Changing JLabel icon dynamically after already adding to GUI?已添加到 GUI 后动态更改 JLabel 图标?
【发布时间】:2013-05-21 13:20:07
【问题描述】:

我在使用 Swing 组件更改 GUI 深处的图标时遇到问题。我正在使用 Java 创建一个有趣的国际象棋游戏,并希望 GUI 的右侧通过在网格中显示取走的棋子来响应棋子。我的问题是,每当我使用新图像调用JLabel 中的setIcon() 函数并将其添加到适当的JPanel 时,它都不会更新。当我第一次setIcon() 时它可以工作,但是在将它添加到 GUI 之后,我无法按照我一直尝试的方式更改它。这是截图,所以你知道我在说什么:

Initial State

After

如您所知,一个棋子已被拿走,但尽管我努力,右侧面板并未反映这一点。

我做了一些研究,以下问题类似:Relevant Question

Camickr 回应说这可能是我尝试更新的 JLabel 的两个实例,我相信这就是我的情况。在将 GUI 设置为初始状态时,我最初将右侧面板上的所有图标设置为 null。这是执行此操作的代码:

for (int i = 0; i < 16; i++)
{
    piece1Labels[i] = new JLabel();
    piece2Labels[i] = new JLabel();
    piece1Panels[i] = new ChessSpace(playerDeadPieceTile);
    piece2Panels[i] = new ChessSpace(playerDeadPieceTile);
    piece1Labels[i].setPreferredSize(new Dimension(67,66));
    piece2Labels[i].setPreferredSize(new Dimension(67,66));
    piece1Labels[i].setIcon(null);
    piece2Labels[i].setIcon(null);
    piece1Panels[i].add(piece1Labels[i]);
    piece2Panels[i].add(piece2Labels[i]);
    player1PiecePanel.add(piece1Panels[i]);
    player2PiecePanel.add(piece2Panels[i]);
}

ChessSpace 扩展JPanel 的piece1Panels 数组中的第一个面板上调用初始化后,我尝试更改其中一个面板:

//Try to change right panel icon after GUI setup
    piece1Labels[0] = new JLabel();
    piece1Panels[0] = new ChessSpace(playerDeadPieceTile);
    piece1Labels[0].setPreferredSize(new Dimension(67,66));
    piece1Labels[0].setIcon(new ImageIcon("C:/Users/Shasta/workspacejava/chess/images/terranpawn.jpg"));
    piece1Panels[0].add(piece1Labels[0]);

piece1Labels 和piece1Panels 是扩展JFrame 的类的变量。我认为问题在于我只是在更新类变量,而不是更新添加到 GUI 的实例。

编辑: 正如 Alican Ozgoren 和 Hovercraft Full Of Eels 指出的那样,我不应该声明 JLabel 的新实例,它们是多余的。

以下代码行似乎可以满足我的要求:

//Try to change right panel icon after GUI setup
    piece1Labels[0].setIcon(new ImageIcon("C:/Users/Shasta/workspacejava/chess/images/terranpawn.jpg"));

【问题讨论】:

  • 为什么每次要更改图标、大小等时都创建一个新的 JLabel?更改现有标签的首选项。另外,您进行更改后是否尝试致电repaint()
  • 正如@AlicanOzgoren 所说,您不应该为此创建新的JLabel,而只需通过其setIcon(Icon icon) 方法更改当前JLabel 的图标。这样做,甚至不需要打电话给repaint()

标签: java swing icons jpanel jlabel


【解决方案1】:

正如我们所指出的,只需设置 JLabel 的图标。但还有一件事——不要像你在这里所做的那样继续阅读图标:

piece1Labels[0].setIcon(new ImageIcon(
         "C:/Users/Shasta/workspacejava/chess/images/terranpawn.jpg"));

而是在程序开始时读取一次图标,并将它们存储在变量中,以便获得:

piece1Labels[0].setIcon(terranpawnIcon);

我还将它们作为资源而不是文件读入,以便您以后可以将图像存储在 jar 文件中并使用它们。

【讨论】:

    【解决方案2】:

    只需创建一个线程来更新 JLable Icone 请参见下面的代码

    包self.wing.practice.image; 导入 javax.swing.*;

    /** * * @author ASHISH KUMAR MISHRA * */ 公共类 ImageDemo {

    public ImageDemo() {
        JFrame jfrm = new JFrame("Image Demo");
        jfrm.setSize(200, 150);
        jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel label = new JLabel();
        jfrm.add(label);
        new ImageUpdator(label).start();
        jfrm.setVisible(true);
    
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
    
            public void run() {
                // TODO Auto-generated method stub
                new ImageDemo();
            }
        });
    }
    

    }

    我创建了一个线程,我在 Constructur 中向其传递 Jlabel。请参阅下面我的线程在做什么

    包装self.wing.practice.image;

    导入 java.io.File;

    导入 javax.swing.ImageIcon; 导入 javax.swing.JLabel;

    /** * * @author ASHISH KUMAR MISHRA * */ 公共类 ImageUpdator 扩展线程 {

    String imagePath = "C:\\Users\\Public\\Pictures\\Sample Pictures";
    File imageDir = new File(imagePath);
    JLabel label = null;
    
    ImageUpdator(JLabel label) {
        this.label = label;
    }
    
    public void run() {
    
        ImageIcon imageIcon = null;
    
        if (imageDir.isDirectory()) {
            File[] files = imageDir.listFiles();
            for (int i = 0;; i++) {
                i = i % files.length;
                File currentFile = files[i];
                if (currentFile.getName().endsWith(".jpg"))
                    ;
                {
                    imageIcon = new ImageIcon(currentFile.getAbsolutePath());
                    label.setName(currentFile.getName().substring(0,
                            currentFile.getName().indexOf('.')));
                    label.setIcon(imageIcon);
                    label.setHorizontalAlignment(JLabel.CENTER);
                    try {
                        Thread.sleep(700);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
                }
    
            }
        }
    }
    

    }

    标题

    【讨论】:

      猜你喜欢
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2014-07-13
      • 1970-01-01
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      相关资源
      最近更新 更多