异常
关于在swing的一个事件监听器中修改了数组成员变量内容后,再在另一个事件监听器中获取数组成员变量的值发现仍然是初始化时的值没有获取到在另一个事件监听器对它的修改。
代码如下:
public class Test2 extends JPanel implements MouseListener {
int[] nums;
Test2() {
nums = new int[5];
nums[1] = 12;
setFocusable(true);
addMouseListener(this);
add(new JLabel("标签"));
}
public JPanel getPanel() {
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
JButton button = new JButton("按钮");
button.setSize(50, 100);
button.setLocation(50, 50);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(Arrays.toString(nums));
}
});
panel.add(button);
return panel;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("sdfd");
frame.setLocation(120, 120);
frame.setSize(300, 300);
frame.setLayout(new BorderLayout());
frame.add(new Test2(), BorderLayout.NORTH);
frame.add(new Test2().getPanel(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getX() + "," + e.getY());
nums[2] = 55;
nums[4] = 1111;
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
先点击“按钮”获取到初始数组nums的打印内容为结果①,然后用鼠标点击“标签”触发面板的鼠标事件,打印出修改nums数组后的内容,也就是结果②,然后我们再点击”按钮“,发现输出的结果③居然与结果①相等,因为我们已经在先点击了”标签“触发了鼠标监听器事件,修改了nums数组的内容,但从另一个事件监听器中却没有获取到修改的结果,也就是说我们期望结果③等于结果②,但失败。
原因
暂时不得而知。
解决
为数组成员变量添加static关键字修饰,那么它们共享一个变量,修改也会同步,如下:
再次测试结果如下:
关于本次异常出现的场景是在保存小游戏中二维数组(即地图资源数据)中的内容到本地文件,但无论如何保存值都为0,最终发现这个问题。
特别说明:上例中的异常必须是两个JPanel面板中的两个事件监听器中对数组成员变量的修改才会导致这样的问题。
如下这种同一个JPanel面板中两个不同的事件监听器中对数组成员变量的修改不会导致上面的异常。
public class Test2 extends JPanel implements MouseListener, ActionListener {
int[] nums;
Test2() {
nums = new int[5];
nums[1] = 12;
setFocusable(true);
addMouseListener(this);
add(new JLabel("标签"));
JButton button = new JButton("按钮");
button.setSize(50, 100);
button.setLocation(50, 50);
button.addActionListener(this);
add(button);
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("sdfd");
frame.setLocation(120, 120);
frame.setSize(300, 300);
frame.setLayout(new BorderLayout());
frame.add(new Test2(), BorderLayout.NORTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void mouseClicked(MouseEvent e) {
nums[2] = 55;
nums[4] = 1111;
System.out.println(Arrays.toString(nums));
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(Arrays.toString(nums));
}
}