【问题标题】:how to avoid this ClassCastException? [closed]如何避免这个 ClassCastException? [关闭]
【发布时间】:2016-03-31 01:38:55
【问题描述】:

我有一个带有 Nimbus l&f 的 Swing 应用程序。有时我得到这个异常,但我不知道它在哪里触发以及如何避免它,因为所有源都来自跟踪堆栈中的 Java 库类。这是 Java 问题 还是 我的问题

关于我的系统的一些信息:

avaVersion = 1.8.0_20

osName = Linux

osVersion = 3.15.10-201.fc20.x86_64

异常信息:

java.lang.ClassCastException: java.awt.Font cannot be cast to javax.swing.Painter
        javax.swing.plaf.nimbus.NimbusStyle.getBackgroundPainter(NimbusStyle.java:708)
        javax.swing.plaf.nimbus.SynthPainterImpl.paintBackground(SynthPainterImpl.java:99)
        javax.swing.plaf.nimbus.SynthPainterImpl.paintPanelBackground(SynthPainterImpl.java:957)
        javax.swing.plaf.synth.SynthPanelUI.update(SynthPanelUI.java:154)
        javax.swing.JComponent.paintComponent(JComponent.java:777)
        javax.swing.JComponent.paint(JComponent.java:1053)
        javax.swing.JComponent.paintToOffscreen(JComponent.java:5223)
        javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:290)
        javax.swing.RepaintManager.paint(RepaintManager.java:1265)
        javax.swing.JComponent._paintImmediately(JComponent.java:5171)
        javax.swing.JComponent.paintImmediately(JComponent.java:4982)
        javax.swing.RepaintManager$4.run(RepaintManager.java:824)
        javax.swing.RepaintManager$4.run(RepaintManager.java:807)
        java.security.AccessController.doPrivileged(Native Method)
        java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
        javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:807)
        javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:782)
        javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:731)
        javax.swing.RepaintManager.access$1300(RepaintManager.java:64)
        javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1720)
        java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
        java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
        java.awt.EventQueue.access$400(EventQueue.java:97)
        java.awt.EventQueue$3.run(EventQueue.java:697)
        java.awt.EventQueue$3.run(EventQueue.java:691)
        java.security.AccessController.doPrivileged(Native Method)
        java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
        java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
        java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
        java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
java.awt.Font cannot be cast to javax.swing.Painter

编辑:

如果它是一致性并且经常发生,我也许能够弄清楚。

显然我也不可能尝试将 Font 投射到 Painter。

EDIT2:

此处复制完整的异常堆栈。

EDIT3

应用程序 GUI 部分在 SwingUtilities.invokeAndWait() 中启动。

我以前也经常使用我的 Win7 机器,但从未在 Win7 上使用过。此应用程序已存在 1 年。

【问题讨论】:

  • 如果您不尝试将Font 转换为Painter,则可以避免此异常。
  • 您有一个间歇性错误,这高度表明存在并发或线程问题。您是否在 Swing 事件线程上启动 GUI?一定要这样做,尤其是在使用 Nimbus 等一些外观和感觉时。换句话说——在 Runnable 中创建你的 GUI 并使用 SwingUtilities.invokeLater(...) 将其排入 Swing 事件队列。
  • 您必须给我们您的代码...否则我们无法重现问题,也无法真正提供帮助
  • 这里只是一个猜测,但您是否可能传递了一些后来 Nimbus 期望成为 Painter 对象的字体对象。我建议尝试通过监视您创建和使用的任何字体对象来调试这个问题,看看这是否是罪魁祸首。根据您项目的大小,这可以轻松帮助您推断问题或可能不可行......只是一些想法。希望对您有所帮助。
  • @HovercraftFullOfEels - 是的,一些代码会有所帮助。

标签: java swing


【解决方案1】:

您有一个从 Swing GUI 抛出的间歇性异常,高度表明这是一个并发/线程问题。您是否在 Swing event dispatch thread 上启动 GUI?如果没有,请务必执行此操作,尤其是使用 Nimbus 等一些外观。换句话说——在 Runnable 中创建您的 GUI,并使用 SwingUtilities.invokeLater(...) 将其排入 Swing 事件队列。

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        // create your Swing GUI and set the L&F here
    });
}

如果这不是问题,那么仍然寻找其他 Swing 线程问题,可能使用引用的方法之一 here


请在同一问题上查看this bug report。它被关闭为“非问题”,因为:

这绝对是一个多线程问题。

再次,我现在可以自信地说,您的问题是线程问题,解决它的方法是检查您的代码并找出您的代码在哪里违反了 Swing 的线程规则,因为肯定是这样。如果您需要我们的帮助,那么您必须向我们展示您的相关代码,即可能违反 Swing 线程规则的代码。如果您不显示代码,我们无法提供具体帮助。

【讨论】:

  • Swing 只有一个 EDT。如果所有与 GUI 相关的操作都被限制在 EDT 中,那将消除这个问题吗?
  • @peterboston:所有 GUI 操作都应在 EDT 期间调用。所有长时间运行的操作都应在后台线程中调用。找出这是否能解决问题的方法是对其进行测试。
猜你喜欢
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
相关资源
最近更新 更多