我目前正在编写一个程序,在for循环中创建并排列了28个标签,我希望为每个标签添加一个mouseListener。我可以为每个标签添加一个mouseListener,但是当我尝试指定标签号并更改该标签的边框颜色时,我得到一个“从内部类访问本地变量需要声明为final”错误。我理解这个错误背后的原因,但我不能让“labelNum”变量最终,因为它需要改变,因为它在循环中。什么是解决方案解决方案?
for (int c = 0; c < 7; c++) {
for (int d = 0; d < 4; d++) {
labelNum = c*4+d;
inventorySlotLabels[labelNum] = new JLabel();
inventorySlotLabels[labelNum].setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
inventorySlotLabels[labelNum].setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
inventorySlotLabels[labelNum].setBounds(15+d*40+d*10, 15+c*30+c*10, 40, 30);
inventorySlotLabels[labelNum].setIcon(new javax.swing.ImageIcon(getClass().getResource("Item.png")));
inventorySlotLabels[labelNum].addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
headerLabel.setText("Inventory Slot Clicked");
inventorySlotLabels[labelNum].setBorder(BorderFactory.createLineBorder(Color.WHITE));
}
}
}
}
答案 0 :(得分:2)
public void mouseClicked(java.awt.event.MouseEvent evt)
{
headerLabel.setText("Inventory Slot Clicked");
inventorySlotLabels[labelNum].setBorder(BorderFactory.createLineBorder(Color.WHITE));
}
不要依赖标签号变量。从MouseEvent获取标签:
public void mouseClicked(java.awt.event.MouseEvent evt)
{
headerLabel.setText("Inventory Slot Clicked");
//inventorySlotLabels[labelNum].setBorder(BorderFactory.createLineBorder(Color.WHITE));
JLabel label = (JLabel)evt.getSource();
label.setBorder( ... );
}
编辑:
实际上,没有理由创建28个MouseListener。在循环之前,代码应该更像:
MouseListener ml = new MouseListener()
{
public void mouseClicked(java.awt.event.MouseEvent evt)
{
headerLabel.setText("Inventory Slot Clicked");
//inventorySlotLabels[labelNum].setBorder(BorderFactory.createLineBorder(Color.WHITE));
JLabel label = (JLabel)evt.getSource();
label.setBorder( ... );
}
};
然后在你的循环中你只需使用:
inventorySlotLabels[labelNum].addMouseListener( ml );
无论是使用annoymouse内部类还是内部类,更好的设计方法是使用MouseEvent中的源对象,不需要创建28个MouseListener来存储变量来索引Array中的标签。实际上,当您使用这种方法时甚至不需要保留数组,这将进一步简化您的代码,因为现在您不再局限于硬编码值来确定数组的大小。
此外,无需阅读图标28次。只需在循环外读取一次Icon,并将Icon添加到每个标签。您也不需要创建28个边框。只需创建一次边框并分享即可。
最后,您不应该使用setBounds(...)来定位和调整标签大小。使用适当的布局管理器(可能是GridLayout)在网格中显示标签。
答案 1 :(得分:0)
“我得到一个”从内部类访问本地变量需要被声明为final“错误。我理解这个错误背后的原因,但我不能让”labelNum“变量最终,因为它需要改变自它在循环中。这里的解决方案是什么?“
简单回答:解决方法是将对象全局声明为类成员
答案 2 :(得分:0)
简单修复:声明labelNum final。是的,这看起来很奇怪,但它确实有效。
for (int c = 0; c < 7; c++) {
for (int d = 0; d < 4; d++) {
final int labelNum = c*4+d;
...
替代修复就像MJafars(使用内部类)所以我删除了它。
而且,正如我原来(现已大部分删除)帖子所述,@ Camick有适当的解决方案,查看事件源,只创建一个监听器。
答案 3 :(得分:0)
为什么匿名的内部课程?使用一个简单的内部类!
class InventoryMouseListener extends java.awt.event.MouseAdapter {
private int labelNum;
public InventoryMouseListener(int labelNum) {
this.labelNum = labelNum;
}
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
headerLabel.setText("Inventory Slot Clicked");
inventorySlotLabels[labelNum].setBorder(BorderFactory.createLineBorder(Color.WHITE));
}
}
添加侦听器
inventorySlotLabels[labelNum]
.addMouseListener(new InventoryMouseListener(labelNum));
会起作用