如何解决不抛出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 举报,一经查实,本站将立刻删除。