有什么办法可以解决范围问题吗?编写泛型方法以向 JRadioButtonMenuItems 添加侦听器

Is there any way around the scope issue? Writing a generic method to add listeners to JRadioButtonMenuItems

提问人:Lapid Palid 提问时间:11/2/2023 更新时间:11/2/2023 访问量:38

问:

我一遍又一遍地编写相同的代码,因为当我将其编写为自己的方法时,我会遇到范围问题,“局部变量......在封闭范围内定义必须是最终的或有效的最终的”。除了像我一直在做的那样一遍又一遍地编写代码之外,还有什么方法可以解决这个问题吗?

这工作原理:

        monochromeOption.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gameboard.monochromeColor = cO;
                gameboard.monochromeColor_temp = cO;
                gameboard.repaint();
            }
        });
        monochromeOption.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {}
            public void mousePressed(MouseEvent e) {}
            public void mouseReleased(MouseEvent e) {}

            @Override
            public void mouseEntered(MouseEvent e) {
                gameboard.monochromeColor_temp = gameboard.monochromeColor;
                gameboard.monochromeColor = cO;
                gameboard.repaint();
            }

            @Override
            public void mouseExited(MouseEvent e) {
                gameboard.monochromeColor = gameboard.monochromeColor_temp;
                gameboard.repaint();
            }
        });

这不会:

private static <T> void addRadioListenersWithMouseOver(NerdChessGameboard board, JRadioButtonMenuItem button, T toAssign, T gameboardT, T gameboardT_temp) {
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            gameboardT = toAssign;
            gameboardT_temp = toAssign;
            board.repaint();
        }
    });
    button.addMouseListener(new MouseListener() {
        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}

        @Override
        public void mouseEntered(MouseEvent e) {
            gameboardT_temp = gameboardT;
            gameboardT = toAssign;
            board.repaint();
        }

        @Override
        public void mouseExited(MouseEvent e) {
            gameboardT = gameboardT_temp;
            board.repaint();
        }
    });
}

这是范围问题,需要一个变量来最终或有效地最终,我总是围绕它进行编码,但这次真的......丑。我现在已经复制粘贴了同一段代码十几次,我只是看不出有任何原因。我知道这只是 JVM 的工作方式,它这样做是为了避免在其他情况下出现更大的错误。但在这种情况下,这是没有意义的,我想要一个解决它的方法!哈哈。我是否遗漏了什么明显的东西,或者每个使用 Java 的人都只是围绕这个问题编写代码,以换取使用 Java 的其他好处?

Java 局部变量

评论

0赞 Progman 11/2/2023
使用关键字有什么问题?final
0赞 Reilas 11/2/2023
@Progman,看看他们的代码吧!
0赞 Lapid Palid 11/2/2023
这里的两个答案都很好,但真正的答案竟然是我很笨。不知何故,我在脑海中混淆了引用和对象,并认为我可以通过引用。这就是 gameboard.monochromeColor 在原始版本中的内容,这是我为其分配对象的引用。据我所知,没有办法在 Java 中传递引用?如果我错了,请告诉我。

答:

0赞 Reilas 11/2/2023 #1

"...是我遗漏了什么明显的东西,还是每个使用 Java 的人都只是围绕这个问题编写代码,以换取使用 Java 的其他好处?

Java 继承主题通常会涵盖您所描述的问题。

由于要在按钮对象中创建匿名类,因此请封装此资源。

组织数据的方法不止一种,下面是一个基本示例。

class NerdChessGameboard extends JComponent {
    class Example<T> extends JRadioButtonMenuItem implements ActionListener, MouseListener {
        T toAssign, gameboardT, gameboardT_temp;

        @Override
        public void actionPerformed(ActionEvent e) {
            gameboardT = toAssign;
            gameboardT_temp = toAssign;
            NerdChessGameboard.this.repaint();
        }

        public void mouseClicked(MouseEvent e) {}
        public void mousePressed(MouseEvent e) {}
        public void mouseReleased(MouseEvent e) {}

        @Override
        public void mouseEntered(MouseEvent e) {
            gameboardT_temp = gameboardT;
            gameboardT = toAssign;
            NerdChessGameboard.this.repaint();
        }

        @Override
        public void mouseExited(MouseEvent e) {
            gameboardT = gameboardT_temp;
            NerdChessGameboard.this.repaint();
        }
    }
}

评论

0赞 Lapid Palid 11/2/2023
这是个好主意。由于其他原因,我实际上有一段时间就有了这样的东西(虽然是非通用的),但当我认为它没有用时,我就把它扔掉了,完全隔开了。会再试一次
1赞 ControlAltDel 11/2/2023 #2

问题来了:

private static <T> void addRadioListenersWithMouseOver(NerdChessGameboard board, JRadioButtonMenuItem button, T toAssign, T gameboardT, T gameboardT_temp) {
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            gameboardT = toAssign; // right here

问题是 toAssign 是一个方法(即堆栈)变量。调用时,此变量将不再位于堆栈上,因此 actionPerformed 无法引用它。actionPerformed

但。。。

将 final 关键字添加到它,传递给 addRadioListenersW 的值...将在侦听器中自动设置,而不是在调用 actionPerformed 时链接

评论

0赞 Lapid Palid 11/2/2023
在哪里添加“final”关键字?到调用中使用的变量?