为什么 Synth 在尝试应用样式时不断抛出 NullPointerExceptions?
Why does Synth keeps throwing NullPointerExceptions when trying to apply a style?
每当我尝试将样式应用于 JMenu 或 JMenuItem(通过 Synth)时,每当我悬停或单击 JMenuItems 或 JMenu 本身时,我都会收到很多 NullPointerExceptions,堆栈跟踪没有给我任何有用的信息信息,并且没有指向我的任何源文件的任何地方。
我正在正确加载文件并且它 确实 显示样式(除了背景颜色,但除此之外)问题是我得到了很多异常,而一切都是工作正常,程序没有崩溃。
这是合成器 LookAndFeel.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<synth>
<style id="menuBarStyle">
<state>
<color value="GRAY" type="BACKGROUND"/>
</state>
</style>
<bind style="menuBarStyle" type="region" key="MenuBar"/>
<style id="menuStyle">
<insets top="5" bottom="3" right="10" left="10"/>
<state>
<color value="RED" type="BACKGROUND"/>
</state>
</style>
<bind style="menuStyle" type="region" key="Menu"/>
<style id="menuItemStyle">
<insets top="5" bottom="5" left="10" right="3"/>
<state>
<color value="GREEN" type="BACKGROUND"/>
</state>
</style>
<bind style="menuItemStyle" type="region" key="MenuItem"/>
<style id="menuItemAcceleratorStyle">
<state>
<color value="GRAY" type="BACKGROUND"/>
</state>
</style>
<bind style="menuItemAcceleratorStyle" type="region" key="MenuItem"/>
</synth>
这是我加载文件的方式:
private void initUI() {
try {
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(getClass().getClassLoader().getResourceAsStream("LookAndFeel.xml"), getClass());
UIManager.setLookAndFeel(laf);
} catch (ParseException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
这是堆栈跟踪(每当与样式化组件交互时重复打印):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sun.font.FontDesignMetrics$MetricsKey.init(FontDesignMetrics.java:217)
at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:286)
at sun.swing.SwingUtilities2.getFontMetrics(SwingUtilities2.java:1113)
at javax.swing.JComponent.getFontMetrics(JComponent.java:1626)
at sun.swing.MenuItemLayoutHelper.reset(MenuItemLayoutHelper.java:125)
at javax.swing.plaf.synth.SynthMenuItemLayoutHelper.<init>(SynthMenuItemLayoutHelper.java:119)
at javax.swing.plaf.synth.SynthGraphicsUtils.paint(SynthGraphicsUtils.java:501)
at javax.swing.plaf.synth.SynthMenuItemUI.paint(SynthMenuItemUI.java:281)
at javax.swing.plaf.synth.SynthMenuItemUI.update(SynthMenuItemUI.java:245)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
at javax.swing.RepaintManager.run(RepaintManager.java:831)
at javax.swing.RepaintManager.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access00(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
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)
我怀疑问题与 Synth 本身有关,而不是我想的代码,我尝试在互联网上查找 java Synth 的文档和教程,但找不到任何东西相关。
P.S: 我在 之前调用此方法 我开始显示或创建任何摆动组件。
更新(和一个很可能的答案):
我找到了解决问题的方法,但是问题仍然存在,因为我仍然没有得到任何解释 为什么 是问题发生的原因,但我有一个假设.
解决方案:
显然,为了使 XML 文件不显示错误,应将字体样式应用于所有元素,这是解决我在一些实验后发现的问题所需的最低限度:
<style id="defaultElementStyle">
<font name="Verdana" size="12"/>
</style>
<bind style="defaultElementStyle" type="region" key=".*"/>
假设
开始于:
- 只要 JMenu/JMenuItems 的状态发生变化就会抛出 NullPointerException。
- 问题已通过设置全局字体解决属性
我可以安全地推断出问题的根源是调用了一些函数,该函数试图读取已更改状态的字体 属性 *(可能来自堆栈跟踪中的 classes 之一) .然而,在上面提到的情况下,状态的默认字体在 XML 文件(null)中未定义,这导致了 NullPointerException,那么也许 class 足够聪明,可以求助于一些默认字体(显示)并且防止程序完全失败和崩溃。
任何关于这个问题的想法都将不胜感激,因为这个问题似乎根本不常见,需要进一步调查。
每当我尝试将样式应用于 JMenu 或 JMenuItem(通过 Synth)时,每当我悬停或单击 JMenuItems 或 JMenu 本身时,我都会收到很多 NullPointerExceptions,堆栈跟踪没有给我任何有用的信息信息,并且没有指向我的任何源文件的任何地方。
我正在正确加载文件并且它 确实 显示样式(除了背景颜色,但除此之外)问题是我得到了很多异常,而一切都是工作正常,程序没有崩溃。
这是合成器 LookAndFeel.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<synth>
<style id="menuBarStyle">
<state>
<color value="GRAY" type="BACKGROUND"/>
</state>
</style>
<bind style="menuBarStyle" type="region" key="MenuBar"/>
<style id="menuStyle">
<insets top="5" bottom="3" right="10" left="10"/>
<state>
<color value="RED" type="BACKGROUND"/>
</state>
</style>
<bind style="menuStyle" type="region" key="Menu"/>
<style id="menuItemStyle">
<insets top="5" bottom="5" left="10" right="3"/>
<state>
<color value="GREEN" type="BACKGROUND"/>
</state>
</style>
<bind style="menuItemStyle" type="region" key="MenuItem"/>
<style id="menuItemAcceleratorStyle">
<state>
<color value="GRAY" type="BACKGROUND"/>
</state>
</style>
<bind style="menuItemAcceleratorStyle" type="region" key="MenuItem"/>
</synth>
这是我加载文件的方式:
private void initUI() {
try {
SynthLookAndFeel laf = new SynthLookAndFeel();
laf.load(getClass().getClassLoader().getResourceAsStream("LookAndFeel.xml"), getClass());
UIManager.setLookAndFeel(laf);
} catch (ParseException e) {
e.printStackTrace();
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
这是堆栈跟踪(每当与样式化组件交互时重复打印):
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sun.font.FontDesignMetrics$MetricsKey.init(FontDesignMetrics.java:217)
at sun.font.FontDesignMetrics.getMetrics(FontDesignMetrics.java:286)
at sun.swing.SwingUtilities2.getFontMetrics(SwingUtilities2.java:1113)
at javax.swing.JComponent.getFontMetrics(JComponent.java:1626)
at sun.swing.MenuItemLayoutHelper.reset(MenuItemLayoutHelper.java:125)
at javax.swing.plaf.synth.SynthMenuItemLayoutHelper.<init>(SynthMenuItemLayoutHelper.java:119)
at javax.swing.plaf.synth.SynthGraphicsUtils.paint(SynthGraphicsUtils.java:501)
at javax.swing.plaf.synth.SynthMenuItemUI.paint(SynthMenuItemUI.java:281)
at javax.swing.plaf.synth.SynthMenuItemUI.update(SynthMenuItemUI.java:245)
at javax.swing.JComponent.paintComponent(JComponent.java:780)
at javax.swing.JComponent.paint(JComponent.java:1056)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at javax.swing.JComponent.paintChildren(JComponent.java:889)
at javax.swing.JComponent.paint(JComponent.java:1065)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5210)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1579)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1502)
at javax.swing.RepaintManager.paint(RepaintManager.java:1272)
at javax.swing.JComponent._paintImmediately(JComponent.java:5158)
at javax.swing.JComponent.paintImmediately(JComponent.java:4969)
at javax.swing.RepaintManager.run(RepaintManager.java:831)
at javax.swing.RepaintManager.run(RepaintManager.java:814)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:814)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:789)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:738)
at javax.swing.RepaintManager.access00(RepaintManager.java:64)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1732)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:709)
at java.awt.EventQueue.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
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)
我怀疑问题与 Synth 本身有关,而不是我想的代码,我尝试在互联网上查找 java Synth 的文档和教程,但找不到任何东西相关。
P.S: 我在 之前调用此方法 我开始显示或创建任何摆动组件。
更新(和一个很可能的答案):
我找到了解决问题的方法,但是问题仍然存在,因为我仍然没有得到任何解释 为什么 是问题发生的原因,但我有一个假设.
解决方案:
显然,为了使 XML 文件不显示错误,应将字体样式应用于所有元素,这是解决我在一些实验后发现的问题所需的最低限度:
<style id="defaultElementStyle">
<font name="Verdana" size="12"/>
</style>
<bind style="defaultElementStyle" type="region" key=".*"/>
假设
开始于:
- 只要 JMenu/JMenuItems 的状态发生变化就会抛出 NullPointerException。
- 问题已通过设置全局字体解决属性
我可以安全地推断出问题的根源是调用了一些函数,该函数试图读取已更改状态的字体 属性 *(可能来自堆栈跟踪中的 classes 之一) .然而,在上面提到的情况下,状态的默认字体在 XML 文件(null)中未定义,这导致了 NullPointerException,那么也许 class 足够聪明,可以求助于一些默认字体(显示)并且防止程序完全失败和崩溃。 任何关于这个问题的想法都将不胜感激,因为这个问题似乎根本不常见,需要进一步调查。