【发布时间】:2020-04-14 10:27:58
【问题描述】:
我正在为我的游戏制作物品栏 UI,过去一天我一直被这个问题困扰,我会尽我所能,尽可能清楚地解释这个问题。
我有一个为我的库存 UI 创建行的 for 循环,它添加与库存中的项目一样多的行。由于在任何给定时间,库存中可能有不同数量的独特物品,因此它必须具有灵活性。
for (int i = 0; i < p1.getPi().getInventoryLength(); i++) {
itemID = (p1.getPi().generateItem(p1.getPi().getItemID(i)).getItemID());
///////// ITEM ICON ///////////
itemLabel = new JLabel(loadMenuIcon(p1.getPi().generateItem(p1.getPi().getItemID(i)).getIcon(), 20, 20));
gc.weightx = 0.1;
gc.weighty = (i+1 == p1.getPi().getInventoryLength()) ? 1 : 0;
gc.gridx = 0;
gc.gridy = i;
gc.fill = GridBagConstraints.HORIZONTAL;
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.insets = new Insets(0, 0, 0, 0);
inventoryPanel.add(itemLabel, gc);
///////// ITEM NAME ///////////
name = new JTextField(p1.getPi().generateItem(p1.getPi().getItemID(i)).getItemName());
name.setBorder(null);
name.setEditable(false);
name.setHighlighter(null);
name.setFont(inGameFont.getFont());
gc.weightx = 0.7;
gc.weighty = 0;
gc.gridx = 1;
gc.gridy = i;
gc.fill = GridBagConstraints.HORIZONTAL;
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.insets = new Insets(4, 0, 0, 0);
inventoryPanel.add(name, gc);
///////// ITEM COUNT ///////////
amount = new JTextField("x " + p1.getPi().getAmount(i));
amount.setBorder(null);
amount.setEditable(false);
amount.setHighlighter(null);
amount.setFont(inGameFont.getFont());
gc.weightx = 0.1;
gc.weighty = 0;
gc.gridx = 2;
gc.gridy = i;
gc.fill = GridBagConstraints.NONE;
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.insets = new Insets(4, 0, 0, 0);
inventoryPanel.add(amount, gc);
///////// USE BUTTON ///////////
useItem = new JButton("Use");
useItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
InventoryClicks gc = new InventoryClicks(this, itemID);
if (inGameInventoryListener != null) {
inGameInventoryListener.formEventOccurred(gc);
}
}
});
useItem.setFont(inGameFont.getFont());
useItem.setHorizontalAlignment(SwingConstants.CENTER);
useItem.setPreferredSize(new Dimension(60, 18));
useItem.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.LIGHT_GRAY));
gc.weightx = 0.1;
gc.weighty = 0;
gc.gridx = 3;
gc.gridy = i;
gc.fill = GridBagConstraints.REMAINDER;
gc.anchor = GridBagConstraints.FIRST_LINE_END;
gc.insets = new Insets(3, 0, 0, 0);
inventoryPanel.add(useItem, gc);
然而,我面临的问题是添加到我的按钮的动作侦听器最终在我的 itemID 变量中具有相同的值。 这意味着无论我按下哪个按钮,我总是得到相同的最终结果。
inventoryBag.SetInGameInventoryListener(new InGameInventoryListener() {
@Override
public void formEventOccurred(InventoryClicks c) {
System.out.println(c.getID());
}
});
这就是我从按下的按钮中提取信息的方式。
我尝试了许多不同的方法来存储 itemID 变量,但我总是遇到同样的问题,我要么无法访问正确的变量,要么我设法保存了变量但无法在我的侦听器中访问它。 我尝试将 itemID 变量与按钮哈希码一起存储在哈希图中
private HashMap<Integer, Integer> buttonIndex;
public HashMap<Integer, Integer> getButtonIndex() {
return buttonIndex;
}
buttonIndex.put(useItem.hashCode(), itemID);
buttonIndex = inventoryBag.getButtonIndex();
inventoryBag.SetInGameInventoryListener(new InGameInventoryListener() {
@Override
public void formEventOccurred(InventoryClicks c) {
System.out.println(buttonIndex.get(c.getID()));
}
});
如果我能从inventoryClicks 的来源获得正确的密钥,我觉得hashmap 解决方案是正确的。
public class InventoryClicks extends EventObject {
private int id;
public int getID() {
return this.id;
}
public InventoryClicks(Object source, int id) {
super(source);
this.id = id;
}
我希望我设法稍微体面地解释了我的问题,我的程序的逻辑是完全关闭还是有可能起作用?我只是挑选了一些我认为相关的代码,但如果缺少某些内容,我可以上传更多。
【问题讨论】:
-
您能澄清一下“itemID”的类型吗?是原始人吗?班级? Primitive Wrapper(例如:Integer、BigInteger 等...)?
-
@sigur itemID 是一个整数,用于保存相应项目的 id
-
我认为问题可能与在其方法中使用 itemID 操作的 ActionListener 有关;我不确定,但一些 JVM “魔法”可以重用同一个实例。尝试创建一个实现 ActionListener 的类,但它将 itemID 作为构造函数参数并将其存储在对象中;然后这个 ActionListener 使用存储的 itemID 执行操作。
-
看起来每次都获得不同的 itemID。也许您可以打印 itemID 变量或使用调试器来确保 itemID 变量在每次循环中都设置为不同的 id。
标签: java swing jbutton actionlistener