关于在swing的两个JPanel钟一个事件监听器中修改了数组成员变量内容后,再在另一个事件监听器中获取数组成员变量的值发现仍然是初始化时的值没有获取到在另一个事件监听器对它的修改

Posted 二木成林

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于在swing的两个JPanel钟一个事件监听器中修改了数组成员变量内容后,再在另一个事件监听器中获取数组成员变量的值发现仍然是初始化时的值没有获取到在另一个事件监听器对它的修改相关的知识,希望对你有一定的参考价值。

异常

关于在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));
    }
}

以上是关于关于在swing的两个JPanel钟一个事件监听器中修改了数组成员变量内容后,再在另一个事件监听器中获取数组成员变量的值发现仍然是初始化时的值没有获取到在另一个事件监听器对它的修改的主要内容,如果未能解决你的问题,请参考以下文章

Java图形界面Swing

java swing Jpanel 怎么添加一个Jdialog弹出框

如何避免 Swing 中的无限更新循环?

java swing中怎么自由设置鼠标的样式(小手,十字,等待.....)

第十二周

关于Swing中JFrame或JPanel重写paint()方法后再在JFrame或JPanel中添加其他组件出现按钮等组件消失不见只有当鼠标扫过时才会出现的问题