Aaron Medacco Aaron Medacco - 3 months ago 11
Java Question

Changing JLabel icon dynamically after already adding to GUI?

I'm having trouble changing an icon deep in my GUI using Swing components. I'm creating a chess game for fun with Java and want the right side of the GUI to respond when a piece is taken by showing the taken piece in a grid. My problem is that whenever I call the

setIcon()
function within
JLabel
with a new image and add it to the appropriate
JPanel
, it does not update. It works when I
setIcon()
the first time, but after it is added to the GUI, I can't change it the way I have been trying to. Here is screenshots so you know what I'm getting at:

Initial State

After

As you can tell, a pawn has been taken but the right panel does not reflect this despite my efforts.

I did some research and the following question was similar: Relevant Question

Camickr responded in that saying it could be two instances of the JLabel I am trying to update which I believe is what is going in my case. I initially set all of my icons on the right panel to null when setting the GUI up for initial state. Here is the code that does this:

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


and here is me trying to change one of those panels after the initialization has been called on the first panel in the piece1Panels array of
ChessSpace
which extend
JPanel
:

//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 and piece1Panels are variables of a class extending
JFrame
. I believe that the problem is that I'm just updating the class variable and not updating the instance that was added to the GUI.

EDIT:
As Alican Ozgoren & Hovercraft Full Of Eels pointed out I shouldn't have declared new instances of the
JLabel
, they were redundant.

The following line of code seems to do what I want:

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

Answer

As we noted, simply set the Icon of the JLabel. But one more thing -- don't keep reading in the Icons as you're doing here:

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

Instead read the Icons in once at the beginning of your program, and store them in variables so that you get:

piece1Labels[0].setIcon(terranpawnIcon);

I would also read them in as resources not Files so that you can later store your images in your jar file and use them.