Java 处理JButton集合的事件

Java 处理JButton集合的事件,java,swing,arraylist,event-handling,Java,Swing,Arraylist,Event Handling,我正试图创建一个动态界面,它本质上创建了一个由越来越多的面板组成的网格,这些面板看起来与下图类似。我有一些粗略的代码来实现这一点。我在处理添加到ArrayList的JButtons事件方面遇到了一个问题。我知道创建内部类事件处理程序是最好的做法,我如何处理存储在ArrayList中的按比例缩放的按钮数的事件 目前,我已经获得了对象源来实现这一点 全局变量: ArrayList<JButton> buttons = new ArrayList<JButton>(); 在

我正试图创建一个动态界面,它本质上创建了一个由越来越多的面板组成的网格,这些面板看起来与下图类似。我有一些粗略的代码来实现这一点。我在处理添加到ArrayList的JButtons事件方面遇到了一个问题。我知道创建内部类事件处理程序是最好的做法,我如何处理存储在ArrayList中的按比例缩放的按钮数的事件

目前,我已经获得了对象源来实现这一点

全局变量:

ArrayList<JButton> buttons = new ArrayList<JButton>();

在我看来,您创建的不仅仅是
JButtons
的集合。相反,您似乎想要创建一个带有
JButton
的图像/文本集合(如果我错了,请纠正我)。这表明您希望创建一个类,该类封装一个(?)菜单项,其中包含图像的JLabel、文本的
JLabel
、其他组件,以及用户可以按以选择菜单项的
JButton
。这个组件将是一个JPanel,它(这里很重要)使用布局管理器智能地排列其所有组成组件。我建议不要使用
ActionListeners
,而是创建一个扩展
AbstractAction
的独立独立类,您可以使用该类通过
JButton
的构造函数或其
setAction(…)
方法来设置每个
JButton的
操作。然后,您可以将这些JPanel的集合放置在主
JPanel
中,该主
JPanel可能使用
GridLayout
,并将其保存在
JScrollPane

我的建议和代码的细节当然取决于GUI和当前代码的细节

其他“附带”建议:

  • 不要使用
    null
    布局和
    setBounds(…)
    。通常,新手Swing程序员认为这是创建复杂GUI的最简单方法,短期内可能是这样,但从长期来看,当需要维护、升级和增强GUI时,情况并非如此。同样,这样创建的GUI在一个平台和屏幕分辨率上看起来不错,但在其他平台上看起来很糟糕。了解并使用布局管理器
  • 也许您需要一组操作或jbutton,但我不确定您是否需要这些。如果按钮的动作知道要做什么,则不需要收集。该操作可以有一个构造函数,该构造函数传入对菜单项的名称和价格的引用

    • 即使你已经接受了另一个答案,我还是想和你分享我的想法

      我的想法是通过创建JButton的子类在按钮上存储一个数字(可能是一个ID)。 (ID可以是,可能是此按钮当前链接的食品的ID)

      然后编写一个actionListener来获取事件的来源(尽管您似乎认为这是一种不好的做法,但我认为在本例中是有意义的),观察:

      ActionListener al = new ActionListener(){
          @Override
          public void actionPerformed(ActionEvent e){
              FoodButton btn = (FoodButton) e.getSource();
              long id = btn.getId();
      
              //Do something now that you know what button was clicked (id)
          }
      }
      
      让我再次注意,这个actionListener是在循环之前创建的,因此您只需要一个,并且您将为所有按钮分配相同的一个

      然后,在循环中创建FoodButton,而不是创建普通的JButton:

      ActionListener al = new ActionListener(){...};
      for (int i = 0; i < 2; i ++) {
          //...
      
          //Assigning id 'i' here, but you could pick something else
          JButton currentButton = new FoodButton("+", i);
          //...
          currentButton.addActionListener(al);
      
          buttons.add(currentButton);
          panel.add(currentButton);
      }
      
      ActionListener al=newactionListener(){…};
      对于(int i=0;i<2;i++){
      //...
      //在这里分配id“i”,但您可以选择其他内容
      JButton currentButton=newfoodButton(“+”,i);
      //...
      currentButton.addActionListener(al);
      按钮。添加(currentButton);
      面板。添加(当前按钮);
      }
      
      我希望这对你有意义


      另外,作为一个曾经使用过空布局的人,一旦你习惯了使用布局管理器,我相信你会喜欢它们。

      你的方法没有问题,我会说。嗯,性能最终会成为一个问题,使用源代码被认为是一种不好的做法。是的,这就是我想要实现的。谢谢,我一定会试一试的。谢谢!看来我有足够的阅读时间来解决这个问题,这将是我在以前项目中所做的一个飞跃。谢谢你的建议,在过去的几天里我有机会试一试,我的上帝,这比我最初想的要容易得多。布局管理器无疑是前进的方向。这似乎是一个很好的解决方案,我刚刚学到,使用源代码来处理事件是不好的,因为它更需要资源,可能会让我尝试一下,这对我来说是有意义的,我对一些非常新的OO概念有点粗略。
      class FoodButton extends JButton{
          long id;
      
          public FoodButton(String text, long id){
              super(text);
              this.id = id;
          }
          //Perhaps more constructors
      
          public long getId(){
              return id;
          }
      }
      
      ActionListener al = new ActionListener(){
          @Override
          public void actionPerformed(ActionEvent e){
              FoodButton btn = (FoodButton) e.getSource();
              long id = btn.getId();
      
              //Do something now that you know what button was clicked (id)
          }
      }
      
      ActionListener al = new ActionListener(){...};
      for (int i = 0; i < 2; i ++) {
          //...
      
          //Assigning id 'i' here, but you could pick something else
          JButton currentButton = new FoodButton("+", i);
          //...
          currentButton.addActionListener(al);
      
          buttons.add(currentButton);
          panel.add(currentButton);
      }