无法调用 java.x.swing.ActionMap.remove(Object),因为“javax.swing.AbstractButton.getActionMap() 的返回值为 null

Cannot invoke java.x.swing.ActionMap.remove(Object) because the return value of "javax.swing.AbstractButton.getActionMap() is null

提问人:Calex 提问时间:7/30/2023 最后编辑:Calex 更新时间:7/30/2023 访问量:36

问:

我的 Swing 应用程序出现错误,我一辈子都无法弄清楚。

我发现错误发生在线路上,但我找不到修复方法。我不想只是把它注释掉,因为它会弄乱应用程序的外观。aToggleButton.setUI((ButtonUI)primaryUI)

如果没有错误,我希望应用程序加载,并且侧面应用程序栏使用 PrimaryNavigationButtonUI 类中的链接图像正确修饰。

异常日志:

java.lang.NullPointerException: Cannot invoke
    "javax.swing.ActionMap.remove(Object)" because the return value of
    "javax.swing.AbstractButton.getActionMap()" is null     at
    java.desktop/javax.swing.plaf.basic.BasicButtonUI.uninstallListeners(BasicButtonUI.java:262)
        at
    java.desktop/javax.swing.plaf.basic.BasicButtonUI.uninstallUI(BasicButtonUI.java:229)
        at
    java.desktop/javax.swing.JComponent.uninstallUIAndProperties(JComponent.java:755)
        at java.desktop/javax.swing.JComponent.setUI(JComponent.java:730)   at
    java.desktop/javax.swing.AbstractButton.setUI(AbstractButton.java:1758)

AppMenuToggleButtonDecorator:

package com.cthsprojects.apphost.ui.decorator;

import java.awt.Dimension;
import java.awt.Font;

import javax.swing.JToggleButton;
import javax.swing.plaf.ButtonUI;

import com.cthsprojects.common.ui.theme.SPrimaryNavigationToggleButtonUI;
import com.cthsprojects.common.ui.theme.SToggleButtonUI;
import com.cthsprojects.common.ui.util.SwingUtils;
import com.cthsprojects.common.view.adapters.decorators.AdapterDecorator;

public class AppMenuToggleButtonDecorator implements AdapterDecorator<JToggleButton> {
    
    public static final int BUTTON_PRIMARY_NAVIGATION_STANDARD_WIDTH = 116;
    
    public static final int BUTTON_PRIMARY_NAVIGATION_STANDARD_HEIGHT = SwingUtils.scaleY(50);
    
    public static final Dimension BUTTON_PRIMARY_NAVIGATION_STANDARD_SIZE = new Dimension(116, BUTTON_PRIMARY_NAVIGATION_STANDARD_HEIGHT);
    
    private static SPrimaryNavigationToggleButtonUI primaryUI = new SPrimaryNavigationToggleButtonUI();
    
    private static final Font FONT_PRIMARY_NAVIGATION_BUTTON = new Font("Tahoma", 0, 16);
    
    public void decorate(JToggleButton aToggleButton) {
        if (aToggleButton != null && primaryUI != null) {
            System.out.println("aToggleButton equals " + aToggleButton + ". primaryUI equals " + primaryUI);
            aToggleButton.setFont(FONT_PRIMARY_NAVIGATION_BUTTON);
            aToggleButton.setPreferredSize(BUTTON_PRIMARY_NAVIGATION_STANDARD_SIZE);
            aToggleButton.setUI((ButtonUI)getUI());
        }
    }
    
    protected SToggleButtonUI getUI() {
        return (SToggleButtonUI)primaryUI;
    }
}

SPrimaryNavigationToggleButtonUI:

package com.cthsprojects.common.ui.theme;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;

public class SPrimaryNavigationToggleButtonUI extends SToggleButtonUI {
    
    public static ComponentUI createUI(JComponent component) {
        return new SPrimaryNavigationToggleButtonUI();
    }
    
    @Override
    protected Image getButtonImage(AbstractButton abstractButton) {
        Image image = PropertyTheme.toggleButtonPrimaryNavigationBackgroundImage.getImage();
        return image;
    }
    
    @Override
    protected Image getButtonPressedImage(AbstractButton abstractButton) {
        return PropertyTheme.toggleButtonPrimaryNavigationDepressedImage.getImage();
    }
    
    @Override
    protected void paintTickOnSelection(AbstractButton abstractButton, ButtonModel model) {
    }
    
    @Override
    protected void setModelEnabledGraphicsColor(Graphics graphics, ButtonModel model) {
        if ((model.isArmed() && model.isPressed()) || model.isSelected()) {
            graphics.setColor(PropertyTheme.BUTTON_DEFAULT_PRESSED_FOREGROUND_COLOR);
        }
        else {
            graphics.setColor(PropertyTheme.toggleButtonPrimaryNavigationForegroundColor);
        }
    }
    
    @Override
    protected void setColorForDisabledButton(Graphics graphics) {
        graphics.setColor(Color.WHITE);
    }
}

编辑 - 尝试使用 EDT,但仍然抛出相同的错误,修改后的代码:

package com.cthsprojects.apphost.ui.decorator;

import java.awt.Dimension;
import java.awt.Font;

import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.plaf.ButtonUI;

import com.cthsprojects.common.ui.theme.SPrimaryNavigationToggleButtonUI;
import com.cthsprojects.common.ui.theme.SToggleButtonUI;
import com.cthsprojects.common.ui.util.SwingUtils;
import com.cthsprojects.common.view.adapters.decorators.AdapterDecorator;

public class AppMenuToggleButtonDecorator implements AdapterDecorator<JToggleButton> {
    
    public static final int BUTTON_PRIMARY_NAVIGATION_STANDARD_WIDTH = 116;
    
    public static final int BUTTON_PRIMARY_NAVIGATION_STANDARD_HEIGHT = SwingUtils.scaleY(50);
    
    public static final Dimension BUTTON_PRIMARY_NAVIGATION_STANDARD_SIZE = new Dimension(116, BUTTON_PRIMARY_NAVIGATION_STANDARD_HEIGHT);
    
    private static SPrimaryNavigationToggleButtonUI primaryUI = new SPrimaryNavigationToggleButtonUI();
    
    private static final Font FONT_PRIMARY_NAVIGATION_BUTTON = new Font("Tahoma", 0, 16);
    
    public void decorate(final JToggleButton aToggleButton) {
        java.awt.EventQueue.invokeLater(new Runnable() {    
            public void run() {
                aToggleButton.setFont(FONT_PRIMARY_NAVIGATION_BUTTON);
                aToggleButton.setPreferredSize(BUTTON_PRIMARY_NAVIGATION_STANDARD_SIZE);
                aToggleButton.setUI((ButtonUI)getUI());
            }
        });
    }
    
    protected SToggleButtonUI getUI() {
        return (SToggleButtonUI)primaryUI;
    }
    
}

接下来可以尝试什么?

java swing nullpointerexception

评论

0赞 Hovercraft Full Of Eels 7/30/2023
您的所有 Swing 代码是否都在 Swing 事件调度线程或“EDT”上启动?
0赞 Hovercraft Full Of Eels 7/30/2023
我之所以这么问,是因为看起来您的代码正在 Swing 库深处启动代码,该代码在尝试取消引用核心 Swing 组件时会抛出 NPE,这表明它在完全构建之前正在访问该组件。
0赞 Calex 7/30/2023
代码未在 Swing 事件调度线程上运行。
0赞 Hovercraft Full Of Eels 7/30/2023
好吧,那很可能是你的问题。在 EDT 上运行时,问题会消失吗?
0赞 Calex 7/30/2023
我尝试使用 EDT,但仍然抛出相同的 NullPointer。(请参阅原始帖子底部修改后的类代码)

答: 暂无答案