通过 revalidate() 和 repaint() 在 Swing 中更新 JMenu 不起作用



在登录过程中,如果管理员正在登录,我想启用名为Admin的JMenuItem。当程序启动时,其可见性设置为 false。因此,当用户单击登录时,我会再次运行 JMenu 并尝试重新创建它,现在将管理员设置为 true。这是我的初始化方法的代码,如果它检测到用户是管理员,则正在运行该方法。该方法位于应用程序使用的 JMenuBar 类内。

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,而是根据程序的管理员状态对其进行修改。您可以为程序提供一个权限枚举,一个带有常规和管理员(可能还有其他(字段的枚举,如下所示:

public enum Privileges {
    REGULAR("Regular"), ADMINISTRATOR("Administrator");
    private String text;
    private Privileges(String text) {
        this.text = text;
    }
    @Override
    public String toString() {
        return text;
    }
}

然后根据程序的权限状态更改 JMenu 的状态。另请注意:不要在菜单上使用鼠标监听器,因为它们不考虑菜单/菜单项/按钮的启用/禁用状态。 例如,下面是我的小型 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;
    }
}

最新更新