Java 在已经添加到GUI后动态更改JLabel图标?

Java 在已经添加到GUI后动态更改JLabel图标?,java,swing,icons,jpanel,jlabel,Java,Swing,Icons,Jpanel,Jlabel,我在使用Swing组件更改GUI深处的图标时遇到问题。我正在用Java创建一个有趣的国际象棋游戏,并希望GUI的右侧通过在网格中显示所取的棋子来响应所取的棋子。我的问题是,每当我使用新图像调用JLabel中的setIcon()函数并将其添加到相应的JPanel,它都不会更新。当我第一次setIcon()时,它就可以工作了,但是在它被添加到GUI之后,我无法以我一直尝试的方式更改它。以下是截图,让您了解我的意思: 正如你所知,一枚棋子被拿走了,但尽管我努力了,右边的面板并没有反映出这一点 我做

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

正如你所知,一枚棋子被拿走了,但尽管我努力了,右边的面板并没有反映出这一点

我做了一些研究,以下问题与此类似:

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]);
}
Piece1Label和Piece1Panel是扩展
JFrame
的类的变量。我认为问题在于我只是更新类变量,而不是更新添加到GUI的实例

编辑: 正如充满鳗鱼的Alican Ozgoren和气垫船所指出的,我不应该声明
JLabel
的新实例,它们是多余的

下面这行代码似乎符合我的要求:

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

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

piece1Labels[0].setIcon(new ImageIcon(
         "C:/Users/Shasta/workspacejava/chess/images/terranpawn.jpg"));
相反,在程序开始时读取图标一次,并将其存储在变量中,以便获得:

piece1Labels[0].setIcon(terranpawnIcon);

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

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

piece1Labels[0].setIcon(new ImageIcon(
         "C:/Users/Shasta/workspacejava/chess/images/terranpawn.jpg"));
相反,在程序开始时读取图标一次,并将其存储在变量中,以便获得:

piece1Labels[0].setIcon(terranpawnIcon);

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

只需创建一个线程来更新JLable iOne,请参阅下面的代码

包装自我、实践、形象; 导入javax.swing.*

/** * *@作者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。请参见下面的“我的线程正在执行的操作”

包装自我、实践、形象

导入java.io.File

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

/** * *@作者ASHISH KUMAR MISHRA * */ 公共类ImageUpdater扩展线程{

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();
                }

            }

        }
    }
}
}


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

包装自我、实践、形象; 导入javax.swing.*

/** * *@作者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。请参见下面的“我的线程正在执行的操作”

包装自我、实践、形象

导入java.io.File

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

/** * *@作者ASHISH KUMAR MISHRA * */ 公共类ImageUpdater扩展线程{

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();
                }

            }

        }
    }
}
}


标题为什么每次要更改图标、大小等时都要创建新的JLabel。?更改现有标签的首选项。另外,您是否尝试在进行更改后调用
repaint()
?正如@AlicanOzgoren所述,您不应该为此目的创建新的JLabel,而只是通过其
设置图标(图标图标)
方法更改当前JLabel的图标。这样做,甚至不需要调用
repaint()
。为什么每次要更改图标、大小等时都要创建一个新的JLabel。?更改现有标签的首选项。另外,您是否尝试在进行更改后调用
repaint()
?正如@AlicanOzgoren所述,您不应该为此目的创建新的JLabel,而只是通过其
设置图标(图标图标)
方法更改当前JLabel的图标。这样做,甚至不需要调用
repaint()