微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

不抛出java.lang.ClassCastException就无法在JPopupMenu中执行JMenuItem操作

如何解决不抛出java.lang.ClassCastException就无法在JPopupMenu中执行JMenuItem操作

我试图让JFrame窗口隐藏起来,并在关闭而不是退出时创建一个托盘图标。然后,托盘图标应具有两个菜单项,这些菜单项可使JFrame窗口再次可见并分别完全退出它。前者可以正常工作,但是当尝试从任务栏图标的jpopupmenu的JMenuItem执行操作时,抛出了以下异常:

Exception in thread "AWT-EventQueue-0" java.lang.classCastException: class javax.swing.JMenuItem cannot be cast to class javax.swing.JFrame (javax.swing.JMenuItem and javax.swing.JFrame are in module java.desktop of loader 'bootstrap')
        at Hierophant$5.actionPerformed(Hierophant.java:94)
        at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
        at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
        at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
        at java.desktop/javax.swing.DefaultButtonModel.setpressed(DefaultButtonModel.java:262)
        at java.desktop/javax.swing.AbstractButton.doClick(AbstractButton.java:369)
        at java.desktop/javax.swing.plaf.basic.BasicmenuItemUI.doClick(BasicmenuItemUI.java:1020)
        at java.desktop/javax.swing.plaf.basic.BasicmenuItemUI$Handler.mouseReleased(BasicmenuItemUI.java:1064)
        at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
        at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
        at java.desktop/java.awt.Component.processEvent(Component.java:6401)
        at java.desktop/java.awt.Container.processEvent(Container.java:2263)
        at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.Lightweightdispatcher.retargetMouseEvent(Container.java:4919)
        at java.desktop/java.awt.Lightweightdispatcher.processMouseEvent(Container.java:4548)
        at java.desktop/java.awt.Lightweightdispatcher.dispatchEvent(Container.java:4489)
        at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
        at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2764)
        at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
        at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
        at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
        at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
        at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
        at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
        at java.desktop/java.awt.EventdispatchThread.pumpOneEventForFilters(EventdispatchThread.java:203)
        at java.desktop/java.awt.EventdispatchThread.pumpEventsForFilter(EventdispatchThread.java:124)
        at java.desktop/java.awt.EventdispatchThread.pumpEventsForHierarchy(EventdispatchThread.java:113)
        at java.desktop/java.awt.EventdispatchThread.pumpEvents(EventdispatchThread.java:109)
        at java.desktop/java.awt.EventdispatchThread.pumpEvents(EventdispatchThread.java:101)
        at java.desktop/java.awt.EventdispatchThread.run(EventdispatchThread.java:90)

这是控制最小化行为的代码jpopupmenu的相关部分。它正在使用扩展JFrame的公共类中没有参数格式化程序的方法运行。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

setDefaultCloSEOperation(WindowConstants.HIDE_ON_CLOSE);

SystemTray tray = SystemTray.getSystemTray();
jpopupmenu menu = new jpopupmenu();
JMenuItem show = new JMenuItem("Show");
JMenuItem exit = new JMenuItem("Exit");

icon = Toolkit.getDefaultToolkit().getimage("icon.png");
trayIcon = new TrayIcon(icon,"Hierophant");
show.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        ((JFrame)e.getSource()).setExtendedState(JFrame.norMAL);
        ((JFrame)e.getSource()).setExtendedState(((JFrame)e.getSource()).getExtendedState() & (~JFrame.ICONIFIED));
        pack();
    }
});
exit.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        ((JFrame)e.getSource()).dispose();
    }
});
menu.add(show);
menu.addSeparator();
menu.add(exit);
trayIcon = new TrayIcon(icon,"Hierophant");
trayIcon.setimageAutoSize(true);
trayIcon.addMouseListener(new MouseAdapter() {
    public void showPopup(MouseEvent e) {
        if (e.isPopupTrigger()) {
            menu.setLocation(e.getX(),e.getY());
            menu.setInvoker(menu);
            menu.setVisible(true);
        }
    }
    @Override
    public void mouseReleased(MouseEvent e) {
        showPopup(e);
    }
    public void mousepressed(MouseEvent e) {
        showPopup(e);
    }
});
try {
    tray.add(trayIcon);
} catch (AWTException e) {
    e.printstacktrace();
}
addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        ((JFrame)e.getSource()).setExtendedState(JFrame.ICONIFIED);
        ((JFrame)e.getSource()).setExtendedState(((JFrame)e.getSource()).getExtendedState() | JFrame.ICONIFIED);
    }
});

代码可能不是最漂亮的,但是对于导致Java引发此异常的原因,我仍然不知所措。特别是在某些地方,我搞砸了吗?

解决方法

正如评论者所指出的,JFrame绝对不是您活动的来源。

如果您希望此确切的代码不引发异常,则只需在调用强制转换为JFrame时捕获异常:

try
{
    (JFrame) e.getSource(); 
}
catch(ClassCastException e)
{
    // nothing
}

您可能想做的是获取事件源Component,然后获取该Container的父级Component

它可能看起来像这样:

if(e.getSource() instanceof Component)
{
    Component component = (Component) e.getSource();

    if(component.getParent() instanceof JFrame)
    {
        JFrame frame = (JFrame) component;

        frame.setExtendedState(JFrame.NORMAL);
    }
}
,

前者工作正常,但是当尝试从任务栏图标的JPopupMenu中的JMenuItem执行操作时,抛出了以下异常:...

前者之所以有效,是因为您将WindowListener添加到JFrame。

后者不起作用,因为您将ActionListener添加到JMenuItem。

...线程“ AWT-EventQueue-0”中的异常java.lang.ClassCastException:无法将类javax.swing.JMenuItem强制转换为类javax.swing.JFrame

您对该异常感到困惑吗?如果单击JMenuItem,为什么会认为可以将ActionEvent的源视为JFrame?

您在论坛中的问题应该是:给定JMenuItem,如何访问框架?

为此,您可以尝试:

JMenuItem menuItem = (JMenuItem)e.getSource();
Window window = SwingUtilitiels.windowForComponent( menuItem );
window.dispose();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。