1

I sometimes see the following stacktrace running tests built with UISpec4j

java.lang.ClassCastException: org.uispec4j.interception.toolkit.Empty$DummyGraphics2D cannot be cast to sun.java2d.SunGraphics2D
    at java.awt.Component$BltBufferStrategy.getDrawGraphics(Component.java:4348)
    at javax.swing.BufferStrategyPaintManager.prepare(BufferStrategyPaintManager.java:522)
    at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:276)
    at javax.swing.RepaintManager.paint(RepaintManager.java:1265)
    at javax.swing.JComponent._paintImmediately(JComponent.java:5167)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4978)
    at javax.swing.JComponent.paintImmediately(JComponent.java:4990)
    at javax.swing.AbstractButton.doClick(AbstractButton.java:371)
    ...

The root cause appears to be naughty JDK code doing a downcast to SunGraphics2D rather than java.awt.Graphics2D in java.awt.Component.BltBufferStrategy.getDrawGraphics()

    /**
     * @return the draw graphics
     */
    public Graphics getDrawGraphics() {
        revalidate();
        Image backBuffer = getBackBuffer();
        if (backBuffer == null) {
            return getGraphics();
        }
        SunGraphics2D g = (SunGraphics2D)backBuffer.getGraphics();
        g.constrain(-insets.left, -insets.top,
                    backBuffer.getWidth(null) + insets.left,
                    backBuffer.getHeight(null) + insets.top);

Am I doing something wrong as I cannot find any references to this elsewhere..?

Workarounds? All I can think to do is to swallow the exception in my test, not ideal.

Adam
  • 35,919
  • 9
  • 100
  • 137

1 Answers1

0

This appears an undocumented feature of JDK which is only exposed when a different implementation of Graphics2D is used as it with the UISpec4J testing framework

Further debugging reveals this only happens on some platforms where acceleration is used. The route through javax.swing.JComponent._paintImmediately(int, int, int, int) differs if double buffering is enabled the exception is thrown

As a workaround this can be disabled with the following which avoids the exception

RepaintManager.currentManager(null).setDoubleBufferingEnabled(false);
Adam
  • 35,919
  • 9
  • 100
  • 137