I am trying to use JTextPanesome CSS stylesheet to display some HTML code. This means that I use the HTMLEditorKitand classes StyleSheet. I know that everyone HTMLEditorKitsuses the same standard instance StyleSheet, so if you change this default style sheet object, you apply the changes at the application level (all components that display HTML).
But in my example, I thought I avoided this by creating my own instance StyleSheetbased on the default. However, this does not work, as seen on the display JTree, which displays according to the style sheet, which is intended only for applying to JTextPane.
import java.awt.*;
import javax.swing.*;
import javax.swing.text.html.*;
import javax.swing.tree.*;
public class TextPaneCssSpill extends JFrame {
private JTextPane textPane;
private JTree tree;
private JSplitPane splitPane;
public TextPaneCssSpill() {
HTMLEditorKit hed = new HTMLEditorKit();
StyleSheet defaultStyle = hed.getStyleSheet();
StyleSheet style = new StyleSheet();
style.addStyleSheet(defaultStyle);
style.addRule("body {font-family:\"Monospaced\"; font-size:9px;}");
style.addRule("i {color:#bababa; font-size:9px;}");
hed.setStyleSheet(style);
textPane = new JTextPane();
textPane.setEditorKit(hed);
textPane.setDocument(hed.createDefaultDocument());
DefaultMutableTreeNode root = new DefaultMutableTreeNode(new MyNode("name", "argument"), true);
root.add(new DefaultMutableTreeNode(new MyNode("name", "argument"), false));
root.add(new DefaultMutableTreeNode(new MyNode("name", "argument"), false));
root.add(new DefaultMutableTreeNode(new MyNode("name", "argument"), false));
root.add(new DefaultMutableTreeNode(new MyNode("name", "argument"), false));
tree = new JTree(root);
tree.setCellRenderer(new MyNodeTreeRenderer());
setLayout(new BorderLayout());
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, textPane, tree);
add(splitPane);
pack();
setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TextPaneCssSpill().setVisible(true);
}
});
}
private static class MyNode {
private final String name;
private final String argument;
public MyNode(String name, String argument) {
this.name = name;
this.argument = argument;
}
@Override
public String toString() {
return name + " " + argument;
}
}
private static class MyNodeTreeRenderer extends DefaultTreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (value instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
if (node.getUserObject() instanceof MyNode) {
MyNode mynode = (MyNode) node.getUserObject();
setText("<html>" + mynode.name + " <i>" + mynode.argument);
}
}
return this;
}
}
}

So, how to properly initialize these objects so that there is no CSS spilling in the application (so that the text panel is displayed in accordance with CSS, but the tree does not work)?
Note: a red underline in the above image indicates a spill problem and was later added by me (no, this is not a visualization tool).