Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different JEditorPanes show html content, using the same css rules

Tags:

java

html

css

swing

A simple swing application draws two independent JDialogs, that contains different JEditorPanes with different html content. In one JEditorPane we use css rules to set borders of table visible. But another JEditorPane uses the same css rules and draws 3px table border as well, but it shouldn't (we do not set it explicitly). Why do they use the same css rules and how we can fix it?

public static void main(String args[]) {
    String text1 = "<html><body><table><tr><td>somthing ONE</td></tr></table></body></html>";
    String text2 = "<html><body><table><tr><td>somthing TWO</td></tr></table></body></html>";

    JDialog jd = new JDialog();
    JEditorPane jep = new JEditorPane();
    HTMLEditorKit kit = new HTMLEditorKit();
    HTMLDocument doc = (HTMLDocument) kit.createDefaultDocument();
    jep.setEditorKit(kit);
    jep.setDocument(doc);
    setCSS(kit);
    jep.setText(text1);
    jd.getContentPane().add(jep);
    jd.pack();  
    jd.setVisible(true);

    JDialog jd2 = new JDialog();
    JEditorPane jep2 = new JEditorPane();
    HTMLEditorKit kit2 = new HTMLEditorKit();
    HTMLDocument doc2 = (HTMLDocument) kit2.createDefaultDocument();
    jep2.setEditorKit(kit2);
    jep2.setDocument(doc2);
    //We do not install css rules explicitly here
    jep2.setText(text2);
    jd2.getContentPane().add(jep2);
    jd2.pack();
    jd2.setVisible(true);
}


public static void setCSS(HTMLEditorKit kit) {
    StyleSheet styleSheet = kit.getStyleSheet();
    styleSheet.addRule("td {border-width: 3px; border-style: solid; border-color: #000000;}");
    kit.setStyleSheet(styleSheet);
}

UPD: As Freek de Bruijn said, it is not a bug and it is documented. So when we set or get StyleSheet in HTMLEditorKit, it uses StyleSheet from AppContext and therefore it shares StyleSheet between all instances of HTMLEditorKit, so the only way to solve this problem is to override HTMLEditorKit's methods. I did it in this way:

public static class CustomKit extends HTMLEditorKit {
    private StyleSheet styles;

    @Override
    public void setStyleSheet(StyleSheet styleSheet) {
        styles = styleSheet;
    }
    @Override
    public StyleSheet getStyleSheet() {
        if (styles == null) {
            styles = super.getStyleSheet();
        }
        return styles;
    }
}

And setCSS method now looks like:

public static void setCSS(CustomKit kit) {
    StyleSheet styleSheet = new StyleSheet();
    styleSheet.addRule("td {border-width: 3px; border-style: solid; border-color: #000000;}");
    kit.setStyleSheet(styleSheet);
}
like image 918
shiv Avatar asked Nov 18 '15 12:11

shiv


Video Answer


1 Answers

It appears that the StyleSheet object is shared by all HTMLEditorKit instances. From the Javadoc comment of the HTMLEditorKit.getStyleSheet method:

* Get the set of styles currently being used to render the
* HTML elements.  By default the resource specified by
* DEFAULT_CSS gets loaded, and is shared by all HTMLEditorKit
* instances.
like image 60
Freek de Bruijn Avatar answered Oct 24 '22 23:10

Freek de Bruijn