为什么这些JMenuItems不能有ActionListener

问题描述 投票:0回答:1

当我借助方法创建 JMenuItem 时,除了 ActionListener 不起作用之外,一切正常,(如果您可以推荐一本手册来详细介绍这方面的内容,请随时发送)

    public JMenuBar menuBar;
    
    public JMenu mnArchivo, mnMante, mnVentas, mnConfig, mnAyuda;
    
    public JMenuItem itmSalir, 
                     itmConsulCocina, itmModCocina, itmListCocina,
                     itmVender, itmGenReport,
                     itmConfigDesc, itmConfigObse, itmConfigCantOp, itmConfigCuotDiaria,
                     itmAcercaDe;
    
    public Home() {
        setTitle("Tienda 1.0");
        setBounds(0, 0, 900, 600);
        getContentPane().setLayout(null);
        
        menuBar = new JMenuBar();
        setJMenuBar(menuBar);
        
        mnArchivo = new JMenu("Archivo");
        menuBar.add(mnArchivo);
        
        mnVentas = new JMenu("Ventas");
        menuBar.add(mnVentas);
        
        //JMenuItem made with method (DOESN'T WORKS)
        addJMenuItem(itmSalir, "Salir", mnArchivo);
        
        //JMenuItem explicitly stated (WORKS)
        itmVender = new JMenuItem("Vender");
        itmVender.addActionListener(this);
        mnVentas.add(itmVender);
        
        setVisible(true);
    }
    
    public void addJMenuItem(JMenuItem itm, String name, JMenu mn) {
        itm = new JMenuItem(name);
        itm.addActionListener(this);
        mn.add(itm);
    }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        //this doesn't changes color
        if(e.getSource() == itmSalir) {
            getContentPane().setBackground(Color.red);
        }
        //this changes color
        if(e.getSource() == itmVender) {
            getContentPane().setBackground(Color.pink);
        }
    }
    
    public static void main(String[] args) {
        Home home = new Home();
    }
}

我开始使用方法来保存代码(并学习如何使用它们 xP)

java eclipse
1个回答
0
投票

这又回到了信息如何传入/传出方法的核心。在

itm = new JMenuItem(name);
内部执行
addJMenuItem
不会将
JMenuItem
实例分配给该方法外部使用的参数值。它只是创建一个新的引用,它不再指向原始参数,并且当方法返回时,它实际上会丢失。

本质上,当您将对象传递给方法时,该方法可以更改对象属性,但是,更改对该对象的引用(例如为其分配新对象或实例)将不会在该方法返回时反映出来。

这很重要,因为当您执行

addJMenuItem(itmSalir, "Salir", mnArchivo);
时,当方法返回时,
itmSalir
仍然会是
null

这意味着当您调用

actionPerformed
方法时...

@Override
public void actionPerformed(ActionEvent e) {
    //this doesn't changes color
    if(e.getSource() == itmSalir) {
        getContentPane().setBackground(Color.red);
    }
    //this changes color
    if(e.getSource() == itmVender) {
        getContentPane().setBackground(Color.pink);
    }
}

itmSalir
永远不会与源匹配,因为
itmSalir
null

您可以通过在代码中添加一些额外的打印语句来看到这一点。

如果你想使用这种工厂方法,你必须做一些更像......的事情

public JMenuItem addJMenuItem(String name, JMenu mn) {
    JMenuItem itm = new JMenuItem(name);
    itm.addActionListener(this);
    mn.add(itm);
    return itm;
}

然后你会被用来做类似...

itmSalir = addJMenuItem("Salir", mnArchivo);

这是 Java 工作原理的核心概念。有关更多详细信息,请参阅将信息传递给方法或构造函数。您可能还想看看 Java 是“按引用传递”还是“按值传递”?

© www.soinside.com 2019 - 2024. All rights reserved.