I’m using java swing components to build up a goofy, very simple RPG java app, and I’ve run into this weird behavior where when I click on a JButton. Here’s my code:
package gameplay;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GameplayUI extends JPanel {
GameplayManager gpm;
ImageIcon linedPaper;
ImageIcon axeIcon;
ImageIcon daggersIcon;
ImageIcon swordIcon;
ImageIcon slimeIcon;
ImageIcon gremlinIcon;
ImageIcon ogreIcon;
JLabel background;
public GameplayUI(GameplayManager gpm){
this.gpm = gpm;
linedPaper = new ImageIcon(this.getClass().getResource("/images/linedpaper.jpeg"));
background = new JLabel(linedPaper);
axeIcon = new ImageIcon(this.getClass().getResource("/images/axeIcon.png"));
daggersIcon = new ImageIcon(this.getClass().getResource("/images/daggersIcon.png"));
swordIcon = new ImageIcon(this.getClass().getResource("/images/swordIcon.png"));
slimeIcon = new ImageIcon(this.getClass().getResource("/images/slimeIcon.png"));
gremlinIcon = new ImageIcon(this.getClass().getResource("/images/gremlinIcon.png"));
ogreIcon = new ImageIcon(this.getClass().getResource("/images/ogreIcon.png"));
background.setIcon(linedPaper);
add(background);
CharacterCreationOverlay();
System.out.println("daggersIcon status: " + daggersIcon.getImageLoadStatus());
}
public void CharacterCreationOverlay(){
JPanel weaponSelectPanel = new JPanel(new MigLayout("debug", "[250][250][250]", ""));
JLabel instructionLabel = new JLabel("Select a weapon:");
nameLabel.setFont(new Font("Serif", Font.BOLD, 30));
//Daggers Button
JButton daggersButton = new JButton(daggersIcon);
daggersButton.setMinimumSize(new Dimension(85, 85));
daggersButton.setBackground(new Color(0,0,0,0));
daggersButton.setRolloverEnabled(false);
daggersButton.setContentAreaFilled(false);
daggersButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
//Sword Button
JButton swordButton = new JButton(swordIcon);
swordButton.setMinimumSize(new Dimension(79, 120));
swordButton.setBackground(new Color(0,0,0,0));
swordButton.setRolloverEnabled(false);
swordButton.setContentAreaFilled(false);
swordButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
//Axe Button
JButton axeButton = new JButton(axeIcon);
axeButton.setMinimumSize(new Dimension(79, 120));
axeButton.setBackground(new Color(0,0,0,0));
axeButton.setRolloverEnabled(false);
axeButton.setContentAreaFilled(false);
axeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
//add components to weaponSelectPanel
weaponSelectPanel.add(instructionLabel, "cell 0 1");
weaponSelectPanel.add(daggersButton, "cell 0 2, grow");
weaponSelectPanel.add(swordButton, "cell 1 2, grow");
weaponSelectPanel.add(axeButton, "cell 2 2, grow");
weaponSelectPanel.setBounds(75,75, 600, 850);
weaponSelectPanel.setBackground(new Color(0,0,0,0));
background.add(weaponSelectPanel);
}
}
So the structure of the components is:
- GameplayUI which extends JPanel has a JLabel called background.
- background is a label and has its icon set to a lined paper ImageIcon.
- background has a JPanel called weaponSelectPanel.
- weaponSelectPanel has a JLabel called instructionLabel, and three Icon-Only buttons with Icons which have transparency.
At first when I moused over any of the buttons, I was seeing the background, frame title, and instruction JLabels superimposed within the button being rolled over. I then added “setRolloverEnabled(false)” to all three, and that behavior stopped. However, the same behavior still happens when I click on any of the buttons.
It seems like maybe there’s something going on with the ChangeListener where when a component is touched, the image of anything I’ve touched with the mouse gets superimposed over whatever I’m clicking on, as well as whatever I have previously clicked on. I’m not really certain why this is happening or how to resolve it, hoping someone here may have a clue. I tried setting the background color of the buttons to (0,0,0,0), and setting setContentAreaFilled(false) for the JButtons, but I’m not sure what’s causing the superimposing of other components.
Minimal Reproducer
I think I’ve got a fairly simple breakdown of the bug occurring. It’s just two classes, a Main which calls a Program, and it requires 3 icons named linedpaper.jpeg, DaggersIcon.png, and SwordIcon.png in the src package, which I will attach below.
Here is the Main class:
public class Main {
public static void main(String[] args) {
Program program = new Program();
}
}
And here is the Program class:
import javax.swing.*;
import java.awt.*;
public class Program extends JFrame {
public Program(){
//Instantiate Icons
ImageIcon linedPaper = new ImageIcon(this.getClass().getResource("/linedpaper.jpeg"));
ImageIcon daggersIcon = new ImageIcon(this.getClass().getResource("/DaggersIcon.png"));
ImageIcon swordIcon = new ImageIcon(this.getClass().getResource("/SwordIcon.png"));
ImageIcon axeIcon = new ImageIcon(this.getClass().getResource("/AxeIcon.png"));
//Creating outer JFrame
setTitle("Example Weirdness");
setSize(750,1000);
//Creating JLabel for background image, add to JFrame
JLabel background = new JLabel(linedPaper);
add(background);
//Creating components to overlay atop background
JLabel instructionLabel = new JLabel("Select a weapon: ");
JButton daggersButton = new JButton(daggersIcon);
daggersButton.setFocusable(false);
daggersButton.setMinimumSize(new Dimension(85, 85));
daggersButton.setBackground(new Color(0,0,0,0));
daggersButton.setRolloverEnabled(false);
daggersButton.setContentAreaFilled(false);
JButton swordButton = new JButton(swordIcon);
swordButton.setFocusable(false);
swordButton.setMinimumSize(new Dimension(79, 120));
swordButton.setBackground(new Color(0,0,0,0));
swordButton.setRolloverEnabled(false);
swordButton.setContentAreaFilled(false);
//Creating panel to house overlay components, adding components to panel.
JPanel weaponSelectPanel = new JPanel();
weaponSelectPanel.add(instructionLabel);
weaponSelectPanel.add(daggersButton);
weaponSelectPanel.add(swordButton);
weaponSelectPanel.setBounds(75, 75, 600, 850);
weaponSelectPanel.setBackground(new Color(0,0,0,0));
//Add overlay panel to background
background.add(weaponSelectPanel);
//set JFrame visible
setLocationRelativeTo(null);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
Here are the exact three files I’m using for linedpaper.jpeg – DaggersIcon.png, and SwordIcon.png.
Here is a screenshot of the program at launch:
Here is a screenshot after clicking daggersButton:
Here is a screenshot after clicking swordButton:
Here is a screenshot after clicking daggersButton again:
Scott Warner is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.