Как изменить "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);
}
}
- Посмотрите, как использовать действия
- И как использовать меню (которые будут использовать действия)
- См. Action API для всех ключей действий
Я думаю, вы могли бы сделать что-то вроде этого, что позволило бы вам использовать один пункт меню для обоих действий и изменить его действие / текст в зависимости от того, подключен клиент или нет.
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();
}
}