处理 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
,您可以使用它来设置每个JButton
的Action
,通过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 集合的事件的主要内容,如果未能解决你的问题,请参考以下文章