5

Everywhere I read answers of people finding ways of enabling word wrapping in a JTextPane, but none of them work for me. I'm using an HTMLDocument (to display "text/html" content) and nothing that I have found so far got it to work. The JTextPane always cause the JScrollPane to scroll horizontally. I need the JTextPane to be scrollable, but only vertically.

Would anyone have a workable demo of a word wrapping JTextPane displaying HTML content?

Yanick Rochon
  • 51,409
  • 25
  • 133
  • 214

1 Answers1

2

There are several duplicates of this question, and many answers, but none that I have found have a single-component solution to the problem. This class is based on one of Stanislav's solutions to a similar problem with plain-text wrapping, with a few changes. This solution is tested with Java 1.7.0_55.

import javax.swing.text.Element;
import javax.swing.text.LabelView;
import javax.swing.text.StyleConstants;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;

public class WrappedHtmlEditorKit extends HTMLEditorKit
{
    private static final long serialVersionUID = 1L;

    private ViewFactory viewFactory = null;

    public WrappedHtmlEditorKit()
    {
        super();
        this.viewFactory = new WrappedHtmlFactory();
        return;
    }

    @Override
    public ViewFactory getViewFactory()
    {
        return this.viewFactory;
    }

    private class WrappedHtmlFactory extends HTMLEditorKit.HTMLFactory
    {
        @Override
        public View create(Element elem)
        {
            View v = super.create(elem);

            if (v instanceof LabelView)
            {
                Object o = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);

                if ((o instanceof HTML.Tag) && (o == HTML.Tag.BR))
                {
                    return v;
                }

                return new WrapLabelView(elem);
            }

            return v;
        }

        private class WrapLabelView extends LabelView
        {
            public WrapLabelView(Element elem)
            {
                super(elem);
                return;
            }

            @Override
            public float getMinimumSpan(int axis)
            {
                switch (axis)
                {
                    case View.X_AXIS:
                    {
                        return 0;
                    }
                    case View.Y_AXIS:
                    {
                        return super.getMinimumSpan(axis);
                    }
                    default:
                    {
                        throw new IllegalArgumentException("Invalid axis: " + axis);
                    }
                }
            }
        }
    }
}
Parker
  • 7,244
  • 12
  • 70
  • 92
  • 2
    This is the only solution that's worked for me. I have however had some issues with back to back (to back, to back) of small images not separated by spaces or words. For example a long string of emotes with nothing between them still suffer the same symptoms of the "really long word" problem. I'll comment again if I find an easy fix you can edit in. – gunfulker Oct 22 '15 at 05:59
  • 1
    Thank you so much. I literally searched months for a HTMLEditorKit implementation for the JTextPane that supports WORD wrap and not LETTER wrap. Before I used StanislavL's code that supports only letter wrap which looks terrible. However in opposition to StanislavL's code, your version doesn't highlight & underline hyperlinks. Do you know how to fix this? It would help me a lot as I have no idea on how to adapt/write a custom HTMLEditorKit. – trinity420 Dec 27 '18 at 12:56
  • 1
    @trinity420 The `HTMLEditorKit` supports HTML version 3.2 with some extensions, so you need to adhere to the styling elements that were available then. I recommend posting a new question and linking it here, because the answer will be too long for a comment. – Parker Dec 27 '18 at 13:35