只有最后一个JPanel ActionListener工作

时间:2015-12-24 13:01:09

标签: java swing jpanel actionlistener

我正在为游戏创建一个菜单,并尝试创建4个JPanel,每个JPanel都能够滚动播放器可以使用的头像。

它适用于JPanel的一个实例,但不能超过一个,只有最后一个JPanel才能工作。我认为必须要在JPanels中创建每个组件,但我无法弄明白。

我会发布下面的课程。

@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;
      }
    }
  }

3 个答案:

答案 0 :(得分:2)

你真的需要面向对象这个。这4个菜单元素中的每一个都是一种类型,它们都应该有自己的 playerPlus playerMinus 按钮的实例。

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
    }

}

如果您编写类似这样的类,那么您的menu元素将引用其自己的播放器加减按钮实例。您遇到的问题是您有一个playerPlus和playerMinus实例,这些实例在四个不同的组件中共享。

答案 1 :(得分:1)

在您的方法中,您可以重新创建按钮playerPlus = new JButton(">");

然后在actionPerformed()中通过与字段

进行比较来检查源代码
if (e.getSource() == playerPlus)

该字段仅包含最后创建的按钮,因此条件

if (e.getSource() == playerPlus)
if (e.getSource() == playerMinus)

总是假的。

最简单的方法是定义按钮的名称并在支票中使用名称

playerPlus = new JButton(">");
playerPlus .setName(">");

然后检查

if (e.getSource() instanceof JButton && ">".equals(((JButton)e.getSource()).getName()) ) {
  //do your logic here
}

答案 2 :(得分:0)

这是因为您在班级中将JButtons定义为字段。当您致电playerChoose(int)时,您将playerPlus and playerMinus分配给新JButton的引用。每次调用playerChoose时都会发生这种情况。因此,当ActionListener将事件源(e.getSource())与存储在playerPlus或playerMinus中的引用进行比较时,只有最后定义的引用有效,因为这是上次设置playerPlus / playerMinus的时间。