处理 JButton 集合的事件

Posted

技术标签:

【中文标题】处理 JButton 集合的事件【英文标题】:Handling events for a collection of JButtons 【发布时间】:2015-05-11 04:31:30 【问题描述】:

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

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

全局变量:

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

向面板添加按钮:

    for (int i = 0; i < 2; i ++) 
        int xTotal = 150;
        if (i == 0) 
            xTotal = 132;
        
        else 
            xTotal = 308;
        
        xTotal = xTotal + xTotal;

        JButton currentButton = new JButton("+");
        currentButton.setBounds(xTotal , 375, 45, 25); 
        currentButton.setFont(currentButton.getFont().deriveFont(14f));
        currentButton.addActionListener(new AddHandler());

        buttons.add(currentButton);
        panel.add(currentButton);
    

事件处理程序:

class AddHandler implements ActionListener 

    public void actionPerformed(ActionEvent event) 


        Object source = event.getSource();

        if (source == buttons.get(0)) 
            System.out.println("hello");

        
        else 

            System.out.println("it worked");
        

    

【问题讨论】:

我会说,你的方法没有问题。 嗯,性能最终会成为问题,使用源代码被认为是不好的做法。 【参考方案1】:

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

我的建议和代码的详细信息当然取决于您的 GUI 和当前代码的详细信息。

其他“侧面”建议:

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

【讨论】:

是的,这就是我想要实现的。谢谢,我一定会试一试的。 啊,谢谢!看起来我有很多阅读要做来弄清楚这一点,这将比我在以前的项目中所做的工作有飞跃。 感谢您的建议,过去几天有机会试一试,我的天哪,实现起来比我最初想的要容易得多。布局管理器绝对是前进的方向。【参考方案2】:

即使您已经接受了另一个答案,我还是想分享一下我的想法。

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

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 来获取事件的来源(即使你似乎认为这是不好的做法,我认为在这个例子中它是有道理的),观察:

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);

我希望这对你有一些意义。

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

【讨论】:

似乎是一个很好的解决方案 我刚刚被教导使用源来处理事件是不好的,因为它更需要资源,可能试一试对我来说很有意义,我有点粗略一些面向对象的概念是相当新的。

以上是关于处理 JButton 集合的事件的主要内容,如果未能解决你的问题,请参考以下文章

来自另一个类的 JButton 动作侦听器

使用 JButton 在 Java 中创建自定义按钮

JButton 不会显示另一个 jframe

JavaGUI程序给按钮添加快捷键

透明 JButton

java 界面编程中 JButton问题