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);
}
}