Как изменить "JMenuItem" и его действие в Java

В моем приложении я использовал jmenuitem для выполнения некоторых действий по подключению определенного порта с помощью программирования сокетов. Теперь я хочу, чтобы при нажатии на пункт меню "Подключить", изменить его имя и действие на "отключить". мой код пункта меню "connect" такой:

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); 

и код "отключить" это:

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);

но этот код вызывает добавление дубликата в меню. Я не могу найти никакой помощи в том, как определить, существует ли пункт меню или заменить пункты меню!

3 ответа

Ваше название вопроса говорит само за себя (т.е. Action, но вы используете ActionListener/JMenuItem). С Action (который мы можем использовать вместо JMenuItem), мы можем просто переопределить NAME значение, которое отображается в названии пункта меню. Вот пример.

уведомление menu.add(Action) вместо 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);
    }
}

Я думаю, вы могли бы сделать что-то вроде этого, что позволило бы вам использовать один пункт меню для обоих действий и изменить его действие / текст в зависимости от того, подключен клиент или нет.

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);
    }
}

Может быть, это также поможет вам.
Я положил все это вместе на 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();
    }
}
Другие вопросы по тегам