代码之家  ›  专栏  ›  技术社区  ›  Travisty

仅最后一个JPanel ActionListeners工作

  •  0
  • Travisty  · 技术社区  · 9 年前

    我正在为一个游戏创建一个菜单,并尝试创建4个JPanel,每个JPanel都能够滚动浏览玩家可以使用的化身。

    它可以使用JPanel的一个实例,但不能超过一个,并且只有最后一个JPanel可以工作。我认为这一定与在JPanel中创建每个组件有关,但我无法理解。

    我会在下面发布课程。

    @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 回复  |  直到 9 年前
        1
  •  2
  •   Oliver Watkins    9 年前

    你真的需要 面向对象的 关于这一点。这4个菜单元素中的每一个都是一种类,它们都应该有自己的实例 玩家Plus player减号 按钮

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

    如果您编写这样一个类,那么您的菜单元素将引用自己的播放器加减按钮实例。您面临的问题是,您有一个playerPlus和playerMinus的实例,它们被四个不同的组件共享。

        2
  •  1
  •   StanislavL    9 年前

    在您的方法中,重新创建按钮 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
    }
    
        3
  •  0
  •   Roel van Endhoven    9 年前

    这是因为您定义了 JButtons 作为类中的字段。当你打电话时 playerChoose(int) 您分配 playerPlus and playerMinus 参考新的JButton。每次调用playerChoose时都会发生这种情况。因此,当ActionListener比较事件源( e.getSource() )对于存储在playerPlus或playerMinus中的引用,只有最后定义的引用有效,因为这是最后一次设置playerPlus/playerMins。