Reputation: 315
I'm creating a menu for a game, and trying to create 4 JPanels, each with the ability to scroll through avatars that the player can use.
It works with one instance of the JPanel, but not more than one, and only the last JPanel will work. I think it must be to do with the creation of each component within the JPanels, but I can't figure it out.
I'll post the class below.
@SuppressWarnings("serial")
public class Menu extends JPanel implements ActionListener {
JLabel playerAvatar;
JLabel playerTxt;
JButton playerPlus;
JButton playerMinus;
Font font_1 = new Font("calibri", Font.BOLD, 55);
Font font_2 = new Font("calibri", Font.BOLD, 30);
int playerAvatarCount = -1;
public Menu() {
init();
}
public void init() {
setOpaque(false);
setLayout(new FlowLayout());
setPreferredSize(new Dimension(1000, 800));
JPanel[] players = new JPanel[4];
players[0] = playerChoose(1);
players[1] = playerChoose(2);
players[2] = playerChoose(3);
players[3] = playerChoose(4);
for (int i = 0; i < 4; i++) {
add(players[i]);
}
}
private JPanel playerChoose(int i) {
JPanel plyrPanel = new JPanel();
plyrPanel.setPreferredSize((new Dimension(240, 200)));
plyrPanel.setOpaque(false);
playerAvatar = new JLabel("", SwingConstants.CENTER);
playerAvatar.setIcon(new ImageIcon("C:\\Users\\Travis\\workspace\\BoardGame\\none.png"));
playerAvatar.setBackground(Color.WHITE);
playerAvatar.setOpaque(true);
playerAvatar.setBorder(BorderFactory.createLineBorder(Color.decode("#5B5C5C"), 3));
playerAvatar.setPreferredSize(new Dimension(105, 155));
playerPlus = new JButton(">");
playerPlus.setPreferredSize(new Dimension(60, 155));
playerPlus.setFont(font_1);
playerPlus.setForeground(Color.decode("#5B5C5C"));
playerPlus.setBorder(BorderFactory.createLineBorder(Color.decode("#5B5C5C"), 1));
playerPlus.setBackground(Color.decode("#B2DBA4"));
playerPlus.addActionListener(this);
playerMinus = new JButton("<");
playerMinus.setPreferredSize(new Dimension(60, 155));
playerMinus.setFont(font_1);
playerMinus.setForeground(Color.decode("#5B5C5C"));
playerMinus.setBorder(BorderFactory.createLineBorder(Color.decode("#5B5C5C"), 1));
playerMinus.setBackground(Color.decode("#B2DBA4"));
playerMinus.addActionListener(this);
playerTxt = new JLabel("Player " + i + "", SwingConstants.CENTER);
playerTxt.setFont(font_2);
playerTxt.setOpaque(false);
playerTxt.setForeground(Color.WHITE);
plyrPanel.add(playerMinus);
plyrPanel.add(playerAvatar);
plyrPanel.add(playerPlus);
plyrPanel.add(playerTxt);
validate();
return plyrPanel;
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == playerPlus) {
playerAvatar
.setIcon(new ImageIcon("C:\\Users\\Travis\\workspace\\BoardGame\\frog" + ++playerAvatarCount + ".png"));
}
if (e.getSource() == playerMinus) {
playerAvatar
.setIcon(new ImageIcon("C:\\Users\\Travis\\workspace\\BoardGame\\frog" + --playerAvatarCount + ".png"));
}
if (playerAvatarCount < 0) {
playerAvatar.setIcon(new ImageIcon("C:\\Users\\Travis\\workspace\\BoardGame\\none.png"));
playerAvatarCount = -1;
} else if (playerAvatarCount > 3) {
playerAvatar.setIcon(new ImageIcon("C:\\Users\\Travis\\workspace\\BoardGame\\frog3.png"));
playerAvatarCount = 3;
}
}
}
Upvotes: 0
Views: 55
Reputation: 13499
You really need to be object-oriented about this. Each one of these 4 menu elements is one type of class, and they all should have their own instance of their playerPlus and playerMinus button.
public class MenuElement extends JPanel {
JLabel playerAvatar;
JLabel playerTxt;
JButton playerPlus;
JButton playerMinus;
public void initComponent() {
//lay out your elements here
}
public void addListeners() {
//setUpYour listeners here
}
}
If you write a class like this then your menu element will have a reference to its own instance of the player plus and minus buttons. The problem you are having is that you have one instance of playerPlus and playerMinus which are being shared across four different components.
Upvotes: 2
Reputation: 180
This is because you define the JButtons
as fields in your class. When you call playerChoose(int)
you assign playerPlus and playerMinus
to the reference of a new JButton. This happens for each time playerChoose is called. So, when the ActionListener compares the event source (e.getSource()
) to the reference stored in playerPlus or playerMinus, only the last defined reference works, seeing as that is the last time playerPlus/playerMinus was set.
Upvotes: 0
Reputation: 57381
In your method you recreate buttons playerPlus = new JButton(">");
but then in the actionPerformed() you check source by comparing with the field
if (e.getSource() == playerPlus)
The field contains only the last created button so the conditions
if (e.getSource() == playerPlus)
if (e.getSource() == playerMinus)
are always false.
The simplest way would be to define name for the buttons and use the name in the checks
playerPlus = new JButton(">");
playerPlus .setName(">");
Then check would be
if (e.getSource() instanceof JButton && ">".equals(((JButton)e.getSource()).getName()) ) {
//do your logic here
}
Upvotes: 1