简体   繁体   中英

How to change “JMenuItem” and its' Action in java

in my application i used jmenuitem to perform some action to connecting specific port by socket programming. now, i want when clicked on "Connect" menu item, change it name and action to "disconnect". my "connect" menu item code is this:

connect = new JMenuItem("Connect");
    connect.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            loginForm login = new loginForm();
            login.setVisible(true);

        }
    });
 jpopupMenu.insert(connect, 0); 

and "disconnect" code is this:

disconnect = new JMenuItem("Disonnect");
    disconnect.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                client.disconnect();
            } catch (IOException ex) {
                Logger.getLogger(systemTray.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    });
jpopupMenu.insert(disconnect, 0);

but this code cause for duplicate item adding to Menu. I can't find any help for how to detect menu item is exists or replacing menu items!

Your question title says it all (ie Action , but you are using ActionListener/JMenuItem ). With Action (which we can use instead of JMenuItem ), we can simply override the NAME value, which is what appears in the menu item name. Here's an example.

Notice menu.add(Action) instead of menu.add(JMenuItem)

import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.*;

public class TestMenu {
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(300, 300);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);

        JMenuBar menuBar = new JMenuBar();
        JMenu menu = new JMenu("Menu");

        Action menuAction = new AbstractAction("Connect") {
            private boolean connected = false;
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!connected) {
                    JOptionPane.showMessageDialog(null, "Connected");
                    putValue(NAME, "Disonnect");
                    connected = true;
                } else {
                    JOptionPane.showMessageDialog(null, "Disconnected");
                    putValue(NAME, "Connect");
                    connected = false;
                }     
            }  
        };

        menuBar.add(menu);
        menu.add(menuAction);
        f.setJMenuBar(menuBar);
        f.setVisible(true);
    }
}

I guess you could do something like this, which would allow you to use single menu item for both actions and change its action/text depending on whether the client is connected or not.

private JMenuItem connect = new JMenuItem("Connect");

// ...

connect.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        if (client.isConnected()) {
            disconnect();
        } else {
            connect();
        }
    }
});

// ...

private void connect() {
    loginForm login = new loginForm();
    login.setVisible(true);
    // TODO: You should change the label only if connection actually succeeds
    connect.setText("Disconnect");
}

private void disconnect() {
    try {
        client.disconnect();
        connect.setText("Connect");
    } catch (IOException ex) {
        Logger.getLogger(systemTray.class.getName()).log(Level.SEVERE, null, ex);
    }
}

maybe this also will help you.
I've put it all together on a jpopupmenu

public class Test {

    JPopupMenu popmenu;
    public boolean isConnected = false;

    public Test() {
        JFrame frame = new JFrame();
        frame.setSize(200, 200);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);

        popmenu = new JPopupMenu();
        final JMenuItem connect = new JMenuItem("connect");
        connect.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        if (!isConnected) {
                            System.out.println("connect action");

                            connect();

                            isConnected = true;
                        } else {
                            System.out.println("disconnect action");

                            disconnect();

                            isConnected = false;
                        }
                    }
                });

            }
        });

        popmenu.insert(connect, 0);

        frame.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popmenu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        });
        frame.setVisible(true);
    }

    private void connect() {
        loginForm login = new loginForm();
        login.setVisible(true);
        // TODO: You should change the label only if connection actually
        // succeeds
        connect.setText("Disconnect");
    }

    private void disconnect() {
        try {
            client.disconnect();
            connect.setText("Connect");
        } catch (IOException ex) {
            Logger.getLogger(systemTray.class.getName()).log(Level.SEVERE,
                    null, ex);
        }
    }

    public static void main(String[] args) {
        new Test();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM