6

I am trying to make a small HTML-wysiwyg with a JTextPane but I can't get the BackgroundAction to work. I am using setCharacterAttributes on the StyledDocument of the JTextPane but it seems problematic. The view is ok but the Document is not.

Here is a small demo code showing the problem. There are 2 JTextPane:

  1. I set the background color of my text in the first one
  2. I retrieve the text of the first JTextPane and set it on the second one

    --> They don't show the same thing although they have the same text.

Is there a way to set the background color on the current selected text and have the JTextPane report an updated HTML-text?

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

public class TestDifferentStyles {

    private void initUI() {
        JFrame frame = new JFrame(TestDifferentStyles.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTextPane textPane = new JTextPane();
        final JTextPane textPane2 = new JTextPane();
        textPane2.setEditable(false);
        textPane.setContentType("text/html");
        textPane2.setContentType("text/html");
        textPane.setText("<html><head></head><body><p>Hello world</p></body></html>");
        SimpleAttributeSet set = new SimpleAttributeSet();
        StyleConstants.setForeground(set, Color.GREEN);
        StyleConstants.setBackground(set, Color.BLACK);
        ((StyledDocument) textPane.getDocument()).setCharacterAttributes(0, textPane.getDocument().getLength(), set, false);

        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        panel.add(textPane, gbc);
        panel.add(textPane2, gbc);
        frame.add(panel);
        frame.setSize(500, 400);
        frame.setVisible(true);
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                System.err.println(textPane.getText());
                textPane2.setText(textPane.getText());
            }
        });
    }

    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestDifferentStyles().initUI();
            }
        });
    }

}

The output result (the black border are around each JTextPane): output result

Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • have to wait for @Stanislav, he has solutions for override Carer, Selections and HightLighter, I think this is about UImanager and its XxxResources, – mKorbel Nov 08 '12 at 08:58
  • @mKorbel ok thanks. I will wait for StanislavL then :-) – Guillaume Polet Nov 08 '12 at 09:30
  • See also Charles Bell's `HTMLDocumentEditor`, cited [here](http://stackoverflow.com/a/5899816/230513). – trashgod Nov 08 '12 at 14:01
  • @trashgod Actually I am reusing the Metaphase editor but their BackgroundAction was fuzzy and did not work properly so I tried to fix that. I could not find a `BackgroundColorAction` within your example but Metaphase is based on similar things. – Guillaume Polet Nov 08 '12 at 16:02
  • Ah, `Metaphase Editor`, cited [here](http://stackoverflow.com/a/10167091/230513). You might link to it in this question for future visitors. – trashgod Nov 08 '12 at 18:10
  • 1
    @trashgod yup (we had to tweak it a lot and unfortunately the project does not look very much alive), but [here is the link to the metaphase editor website](http://kenai.com/projects/metaphaseeditor). Thanks for your comments and cheers ;-) – Guillaume Polet Nov 08 '12 at 18:54

1 Answers1

5

Here is the code for an Action that can set the background color:

public class BackgroundColorAction extends StyledEditorKit.StyledTextAction {

    private Color color;

    public BackgroundColorAction(Color color) {
        super(StyleConstants.Background.toString());
        this.color = color;
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        JEditorPane editor = getEditor(ae);
        if (editor == null) {
            return;
        }
        //Add span Tag
        String htmlStyle = "background-color:" + Util.getHTMLColor(color);
        SimpleAttributeSet attr = new SimpleAttributeSet();
        attr.addAttribute(HTML.Attribute.STYLE, htmlStyle);
        MutableAttributeSet outerAttr = new SimpleAttributeSet();
        outerAttr.addAttribute(HTML.Tag.SPAN, attr);
        //Next line is just an instruction to editor to change color
        StyleConstants.setBackground(outerAttr, this.color);
        setCharacterAttributes(editor, outerAttr, false);
    }
}

I had lot of trouble setting background color. But finally, I have managed to crack it.` Sorry I forgot to post the subroutine. Here you go:

/**  
 * Convert a Java Color to equivalent HTML Color.
 *
 * @param color The Java Color
 * @return The String containing HTML Color.
 */
public static String getHTMLColor(Color color) {
    if (color == null) {
        return "#000000";
    }
    return "#" + Integer.toHexString(color.getRGB()).substring(2).toUpperCase();
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
  • Couldn't find an appropriate package for the `Util` class and it doesn't seem to be a field. Could you shed some light on what 'Util' is referring to in this line: `Util.getHTMLColor(color);` – Nick Rippe Nov 08 '12 at 14:39
  • @NickRippe I did not have the time yet to verify the code (will do asap), but I am guessing that it does something like thie: `"#"+String.format("%1$02x%2$02x%3$02x", color.getRed(), color.getGreen(), color.getBlue())` – Guillaume Polet Nov 08 '12 at 15:57
  • Just verified it and it works like a charm. +1 and Accepted answer. – Guillaume Polet Nov 08 '12 at 16:00
  • Thank you, I found the answer to set the background color for a long time, finally found the correct! – oliver Aug 14 '13 at 07:37