Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8034955

JLabel/JToolTip throw ClassCastException for "<html>a<title>"

XMLWordPrintable

    • b09
    • generic

        FULL PRODUCT VERSION :
        java version " 1.7.0_09 " , java version " 1.6.0_37 "

        ADDITIONAL OS VERSION INFORMATION :
        not OS specific

        A DESCRIPTION OF THE PROBLEM :
        Setting the text of a JLabel or the tip text of a JToolTip to " <html>a<title> " (and similar text with <title> *outside* <head>...</head>) throws ClassCastException:

        Seems to be related to bugs 4845362 and 4908714.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Create a JLabel, set its text to " <html>a<title> " , display the label in a Swing GUI. Alternatively, set the tool tip text for any JComponent to " <html>a<title> " and wait for ToolTipManager to display the tip.
          See also the test case below.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        JLabel/JToolTip renders plain text, either " a " or " <html>a<title> " .
        ACTUAL -
          Program exits with ClassCastException, see below.

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        Exception in thread " AWT-EventQueue-0 " java.lang.ClassCastException: javax.swing.JLabel cannot be cast to javax.swing.text.JTextComponent
        at javax.swing.text.html.EditableView.paint(EditableView.java:59)
        at javax.swing.text.BoxView.paintChild(BoxView.java:144)
        at javax.swing.text.BoxView.paint(BoxView.java:416)
        at javax.swing.text.BoxView.paintChild(BoxView.java:144)
        at javax.swing.text.BoxView.paint(BoxView.java:416)
        at javax.swing.text.ParagraphView.paint(ParagraphView.java:587)
        at javax.swing.text.html.ParagraphView.paint(ParagraphView.java:224)
        at javax.swing.text.BoxView.paintChild(BoxView.java:144)
        at javax.swing.text.BoxView.paint(BoxView.java:416)
        at javax.swing.text.html.BlockView.paint(BlockView.java:265)
        at javax.swing.text.BoxView.paintChild(BoxView.java:144)
        at javax.swing.text.BoxView.paint(BoxView.java:416)
        at javax.swing.text.html.BlockView.paint(BlockView.java:265)
        at javax.swing.plaf.basic.BasicHTML$Renderer.paint(BasicHTML.java:464)
        at javax.swing.plaf.basic.BasicLabelUI.paint(BasicLabelUI.java:156)
        at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
        at javax.swing.JComponent.paintComponent(JComponent.java:752)
        at javax.swing.JComponent.paint(JComponent.java:1029)
        at javax.swing.JComponent.paintChildren(JComponent.java:862)
        at javax.swing.JComponent.paint(JComponent.java:1038)
        at javax.swing.JComponent.paintChildren(JComponent.java:862)
        at javax.swing.JComponent.paint(JComponent.java:1038)
        at javax.swing.JLayeredPane.paint(JLayeredPane.java:567)
        at javax.swing.JComponent.paintChildren(JComponent.java:862)
        at javax.swing.JComponent.paintToOffscreen(JComponent.java:5131)
        at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
        at javax.swing.RepaintManager.paint(RepaintManager.java:1224)
        at javax.swing.JComponent.paint(JComponent.java:1015)
        at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:21)
        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:60)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:97)
        at java.awt.Container.paint(Container.java:1780)
        at java.awt.Window.paint(Window.java:3375)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:796)
        at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:713)
        at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:693)
        at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:125)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        package com.yworks.swing;

        import java.awt.EventQueue;
        import java.util.Locale;
        import javax.swing.JFrame;
        import javax.swing.JLabel;

        public class HtmlRenderingTest {
          public static void main( String[] args ) {
            EventQueue.invokeLater(new Runnable() {
              public void run() {
                Locale.setDefault(Locale.ENGLISH);
                final JFrame frame = new JFrame(HtmlRenderingTest.class.getName());
                frame.getContentPane().add(new JLabel( " <html>a<title> " ));
                frame.setVisible(true);
              }
            });
          }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Subclass JLabel and overwrite methods setText and paintComponent:

        class SafeLabel extends JLabel {
          public void setText( final String text ) {
            try {
              super.setText(text);
            } catch (ClassCastException e) {
              if (isHtmlString(getText())) {
                // JDK 1.4/1.5 throw CCE here for invalid HTML
                // ignore - seems to render some text in spite of the exception
              } else {
                throw e;
              }
            }
          }

          protected void paintComponent( final Graphics g ) {
            try {
              super.paintComponent(g);
            } catch (ClassCastException e) {
              if (isHtmlString(getText())) {
                // JDK 1.6/1.7 throw CCE here for invalid HTML
                // ignore - seems to render some text in spite of the exception
              } else {
                throw e;
              }
            }
          }

          public JToolTip createToolTip() {
            final JToolTip tip = new SafeToolTip();
            tip.setComponent(this);
            return tip;
          }

          private static boolean isHtmlString( final String text ) {
            return SafeToolTip.isHtmlString(text);
          }
        }

        class SafeToolTip extends JToolTip {
          public void setTipText( final String tipText ) {
            try {
              super.setTipText(tipText);
            } catch (ClassCastException e) {
              if (isHtmlString(tipText)) {
                // JDK 1.4/1.5 throw CCE here for invalid HTML
                // ignore - seems to render some text in spite of the exception
              } else {
                throw e;
              }
            }
          }

          protected void paintComponent( final Graphics g ) {
            try {
              super.paintComponent(g);
            } catch (ClassCastException e) {
              if (isHtmlString(getTipText())) {
                // JDK 1.6/1.7 throw CCE here for invalid HTML
                // ignore - seems to render some text in spite of the exception
              } else {
                throw e;
              }
            }
          }

          static boolean isHtmlString( final String text ) {
            return BasicHTML.isHTMLString(text);
          }
        }

              alexsch Alexandr Scherbatiy
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: