通过 revalidate() 和 repaint() 更新 Swing 中的 JMenu 不起作用
Update JMenu in Swing via revalidate() and repaint() not working
在登录过程中,如果管理员正在登录我想启用名为Admin的JMenuItem。程序启动时,其可见性设置为 false。因此,当用户再次单击 Log In I 运行 JMenu 并尝试重新创建它时 Admin 现在设置为 true。这是我的初始化方法的代码,如果它检测到用户是管理员,则它是 运行。该方法位于应用程序使用的 JMenuBar class 中。
public void initialize() {
file = new JMenu("File");
file.setName("File Menu");
file.addMouseListener(this);
help = new JMenu("Help");
help.setName("Help Menu");
help.addMouseListener(this);
login = new JMenu("Login");
login.setName("Login Menu");
login.addMouseListener(this);
language = new JMenu("Language");
language.setName("Language Menu");
language.addMouseListener(this);
admin = new JMenu("Admin");
admin.setName("Admin Menu");
if(LoginDialog.AdminLoggedIn) {
admin.setEnabled(true);
} else
admin.setEnabled(false);
admin.addMouseListener(this);
add(file);
add(login);
add(help);
add(language);
add(admin);
this.revalidate();
this.repaint();
}
谢谢。
我建议不要重新创建 JMenu,而是修改它,具体取决于程序的管理员状态。您可以为程序提供一个权限枚举,其中一个包含 REGULAR 和 ADMINISTRATOR(可能还有其他)字段,例如:
public enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
@Override
public String toString() {
return text;
}
}
然后根据程序的权限状态更改 JMenu 的状态。另请注意:不要在菜单上使用 MouseListener,因为它们不符合菜单/菜单项/按钮的 enabled/disabled 状态。例如,这是我的小 MVCE 示例,它使用模型-视图-控制器结构(某种):
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
@SuppressWarnings("serial")
public class MenuChanger extends JPanel {
private CreateMenu createMenu = new CreateMenu();
private MenuChngModel model = new MenuChngModel();
private ButtonGroup buttonGroup = new ButtonGroup();
public MenuChanger() {
setPreferredSize(new Dimension(400, 300));
model.addPropertyChangeListener(MenuChngModel.PRIVILEGES, new ModelListener());
JPanel privilegesPanel = new JPanel();
privilegesPanel.setLayout(new GridLayout(0, 1, 5, 5));
privilegesPanel.setBorder(BorderFactory.createTitledBorder("Privileges"));
for (final Privileges privileges : Privileges.values()) {
JRadioButton rBtn = new JRadioButton(privileges.toString());
if (privileges == Privileges.REGULAR) {
rBtn.setSelected(true);
}
rBtn.addActionListener(e -> {
createMenu.setPrivileges(privileges);
});
buttonGroup.add(rBtn);
privilegesPanel.add(rBtn);
}
add(privilegesPanel);
}
public CreateMenu getCreateMenu() {
return createMenu;
}
private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Privileges privileges = (Privileges) evt.getNewValue();
createMenu.setPrivileges(privileges);
}
}
private static void createAndShowGui() {
MenuChanger mainPanel = new MenuChanger();
JFrame frame = new JFrame("MenuChanger");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getCreateMenu().getMenubar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MenuChngModel {
public static final String PRIVILEGES = "privileges";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
private Privileges privileges = Privileges.REGULAR;
public Privileges getPrivileges() {
return privileges;
}
public void setPrivileges(Privileges privileges) {
Privileges oldValue = this.privileges;
Privileges newValue = privileges;
this.privileges = privileges;
pcSupport.firePropertyChange(PRIVILEGES, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
@Override
public String toString() {
return text;
}
}
class CreateMenu {
private JMenuBar menubar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenu adminMenu = new JMenu("Administrator");
private JMenuItem fileMenuItem = new JMenuItem("File Menu Item");
private JMenuItem adminFileMenuItem = new JMenuItem("Admin File Menu Item");
public CreateMenu() {
fileMenu.setMnemonic(KeyEvent.VK_F);
adminMenu.setMnemonic(KeyEvent.VK_A);
fileMenu.add(fileMenuItem);
fileMenu.add(adminFileMenuItem);
adminMenu.add(new JMenuItem("Foo 1"));
adminMenu.add(new JMenuItem("Foo 2"));
adminFileMenuItem.setEnabled(false);
adminMenu.setEnabled(false);
menubar.add(fileMenu);
menubar.add(adminMenu);
}
public void setPrivileges(Privileges privileges) {
switch (privileges) {
case REGULAR:
adminMenu.setEnabled(false);
adminFileMenuItem.setEnabled(false);
break;
case ADMINISTRATOR:
adminMenu.setEnabled(true);
adminFileMenuItem.setEnabled(true);
break;
default:
break;
}
}
public JMenuBar getMenubar() {
return menubar;
}
}
在登录过程中,如果管理员正在登录我想启用名为Admin的JMenuItem。程序启动时,其可见性设置为 false。因此,当用户再次单击 Log In I 运行 JMenu 并尝试重新创建它时 Admin 现在设置为 true。这是我的初始化方法的代码,如果它检测到用户是管理员,则它是 运行。该方法位于应用程序使用的 JMenuBar class 中。
public void initialize() {
file = new JMenu("File");
file.setName("File Menu");
file.addMouseListener(this);
help = new JMenu("Help");
help.setName("Help Menu");
help.addMouseListener(this);
login = new JMenu("Login");
login.setName("Login Menu");
login.addMouseListener(this);
language = new JMenu("Language");
language.setName("Language Menu");
language.addMouseListener(this);
admin = new JMenu("Admin");
admin.setName("Admin Menu");
if(LoginDialog.AdminLoggedIn) {
admin.setEnabled(true);
} else
admin.setEnabled(false);
admin.addMouseListener(this);
add(file);
add(login);
add(help);
add(language);
add(admin);
this.revalidate();
this.repaint();
}
谢谢。
我建议不要重新创建 JMenu,而是修改它,具体取决于程序的管理员状态。您可以为程序提供一个权限枚举,其中一个包含 REGULAR 和 ADMINISTRATOR(可能还有其他)字段,例如:
public enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
@Override
public String toString() {
return text;
}
}
然后根据程序的权限状态更改 JMenu 的状态。另请注意:不要在菜单上使用 MouseListener,因为它们不符合菜单/菜单项/按钮的 enabled/disabled 状态。例如,这是我的小 MVCE 示例,它使用模型-视图-控制器结构(某种):
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
@SuppressWarnings("serial")
public class MenuChanger extends JPanel {
private CreateMenu createMenu = new CreateMenu();
private MenuChngModel model = new MenuChngModel();
private ButtonGroup buttonGroup = new ButtonGroup();
public MenuChanger() {
setPreferredSize(new Dimension(400, 300));
model.addPropertyChangeListener(MenuChngModel.PRIVILEGES, new ModelListener());
JPanel privilegesPanel = new JPanel();
privilegesPanel.setLayout(new GridLayout(0, 1, 5, 5));
privilegesPanel.setBorder(BorderFactory.createTitledBorder("Privileges"));
for (final Privileges privileges : Privileges.values()) {
JRadioButton rBtn = new JRadioButton(privileges.toString());
if (privileges == Privileges.REGULAR) {
rBtn.setSelected(true);
}
rBtn.addActionListener(e -> {
createMenu.setPrivileges(privileges);
});
buttonGroup.add(rBtn);
privilegesPanel.add(rBtn);
}
add(privilegesPanel);
}
public CreateMenu getCreateMenu() {
return createMenu;
}
private class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
Privileges privileges = (Privileges) evt.getNewValue();
createMenu.setPrivileges(privileges);
}
}
private static void createAndShowGui() {
MenuChanger mainPanel = new MenuChanger();
JFrame frame = new JFrame("MenuChanger");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getCreateMenu().getMenubar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MenuChngModel {
public static final String PRIVILEGES = "privileges";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
private Privileges privileges = Privileges.REGULAR;
public Privileges getPrivileges() {
return privileges;
}
public void setPrivileges(Privileges privileges) {
Privileges oldValue = this.privileges;
Privileges newValue = privileges;
this.privileges = privileges;
pcSupport.firePropertyChange(PRIVILEGES, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
enum Privileges {
REGULAR("Regular"), ADMINISTRATOR("Administrator");
private String text;
private Privileges(String text) {
this.text = text;
}
@Override
public String toString() {
return text;
}
}
class CreateMenu {
private JMenuBar menubar = new JMenuBar();
private JMenu fileMenu = new JMenu("File");
private JMenu adminMenu = new JMenu("Administrator");
private JMenuItem fileMenuItem = new JMenuItem("File Menu Item");
private JMenuItem adminFileMenuItem = new JMenuItem("Admin File Menu Item");
public CreateMenu() {
fileMenu.setMnemonic(KeyEvent.VK_F);
adminMenu.setMnemonic(KeyEvent.VK_A);
fileMenu.add(fileMenuItem);
fileMenu.add(adminFileMenuItem);
adminMenu.add(new JMenuItem("Foo 1"));
adminMenu.add(new JMenuItem("Foo 2"));
adminFileMenuItem.setEnabled(false);
adminMenu.setEnabled(false);
menubar.add(fileMenu);
menubar.add(adminMenu);
}
public void setPrivileges(Privileges privileges) {
switch (privileges) {
case REGULAR:
adminMenu.setEnabled(false);
adminFileMenuItem.setEnabled(false);
break;
case ADMINISTRATOR:
adminMenu.setEnabled(true);
adminFileMenuItem.setEnabled(true);
break;
default:
break;
}
}
public JMenuBar getMenubar() {
return menubar;
}
}