【发布时间】:2021-04-13 14:55:55
【问题描述】:
我正在构建一个包含多个按顺序创建的 JFrame 的游戏。对于其中两个框架(大厅和实际游戏框架),我将 F11 等用户输入用于全屏模式。要进入或离开这个全屏模式,我显然必须处理当前帧并创建一个新帧,因为 setUndecorated() 的设置只能在使帧可见之前设置。
由于 JFrame 中的其他 UI 元素会成为焦点,因此我必须使用键绑定。因此,我开设了一个进入或离开全屏模式的课程。为了阐明是否应该全屏创建 JFrame,我传递了一个 int windowState 作为参数。由于应该可以实例化两个不同的屏幕,因此我不能简单地调用类本身,而是需要查看传递给 Action 事件的帧。
这是我目前尝试做的:
public class EnterFullscreen extends AbstractAction{
private static final long serialVersionUID = 1773898497666165938L;
private JFrame frame;
private Class<?> frameType;
private Constructor<?> c;
public EnterFullscreen(JFrame frame) {
this.frame = frame;
try {
frameType = frame.getClass();
c = frameType.getConstructor(String.class);
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
@Override
public void actionPerformed(ActionEvent e) {
try {
frame.setVisible(false);
if (frame.isUndecorated()) {
c.newInstance(0);
} else {
c.newInstance(1);
}
frame.dispose();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException e1) {
e1.printStackTrace();
}
}
}
错误信息:
java.lang.NoSuchMethodException: de.munchkin.frontend.Lobby.<init>(java.lang.String)
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.getConstructor(Class.java:1825)
at de.munchkin.keybindings.EnterFullscreen.<init>(EnterFullscreen.java:24)
at de.munchkin.frontend.Lobby.<init>(Lobby.java:45)
at de.munchkin.frontend.MatchCreation.lambda$1(MatchCreation.java:169)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6539)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6304)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
at java.awt.Container.dispatchEventImpl(Container.java:2283)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at de.munchkin.keybindings.EnterFullscreen.actionPerformed(EnterFullscreen.java:40)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1668)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2882)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2943)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2845)
at java.awt.Component.processEvent(Component.java:6316)
at java.awt.Container.processEvent(Container.java:2239)
at java.awt.Component.dispatchEventImpl(Component.java:4889)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:835)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1103)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:974)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:800)
at java.awt.Component.dispatchEventImpl(Component.java:4760)
at java.awt.Container.dispatchEventImpl(Container.java:2297)
at java.awt.Window.dispatchEventImpl(Window.java:2746)
at java.awt.Component.dispatchEvent(Component.java:4711)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
at java.awt.EventQueue$4.run(EventQueue.java:733)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
问题是我收到此错误但找不到问题所在,因为我认为我正在做有关此主题的大多数其他 SO 文章所描述的内容: Article 1 Article 2 等等
这些文章中描述的是我需要获取构造函数并在其上调用newInstance(),如果我没有记错的话,我就是这样做的。
那么,我需要做些什么不同的事情才能让它发挥作用?我并没有真正看到与上面链接的其他 SO 帖子中提出的解决方案有任何区别。
【问题讨论】:
-
1) 你是否在某个地方扩展了 JFrame 类?
getClass()返回对象的运行时类型(动态类型);如果您只是使用普通的 JFrame,那么getClass()将只返回类型JFrame。 2)getConstructor(String.class)尝试检索接受String作为参数的构造函数。然而,当您稍后使用它时,您会传递一个整数(0 或 1)。 3)我对你的目标有点困惑,但反思可能是不必要的;可能有简单的设计模式和语言机制可以实现您想要的结果(例如工厂、多态等) -
我能够通过在类上调用
getConstructors()并使用返回数组中的第一个值来使其工作 - 但是数组中也只存储了一个构造函数。我也不会将此作为问题的最终答案,因为这仍然不能回答我将如何通过调用getConstructor()来做到这一点。 -
@Nerdizzle 我的大厅和游戏框架都扩展了 JFrame。这两个类的构造函数都采用原始 int 而不是 Integer,因此这可能是我无法获得正确构造函数的原因,因为我已经尝试将
String.class替换为Integer.class但结果在同一个错误中。我之所以使用反射来做这件事,是因为这是我想到的第一件事。我不确定如何以不同的方式解决这个问题。 -
好吧,您可以只使用类似于传统
clone()范例但默认构造克隆的多态函数。这将需要一个介于JFrame和类层次结构中的游戏/大厅框架之间的类,您将在其中抽象地定义此函数。毕竟,您是在尝试基于对象的动态类型来实现行为;这就是多态性的全部意义所在。
标签: java class generics instance instantiation