Skip to Main Content

Java SE (Java Platform, Standard Edition)

JTextPane View Problem

843805Jan 9 2007 — edited Jan 9 2007
Hey all,

I'm having some trouble manipulating the view of a JTextPane. My goal is to be able to visualize all the whitespace in the pane (spaces as '.', newlines as 'P' etc).

So far I've succeeded in painting over the white space in lines containing other text. However, getting the new lines to be painted onto blank lines (lines just containing a newline and nothing else) has been a problem. It seems that the JTextPane view doesn't both creating a LabelView for lines that have nothing but a newline on them, so my paint method never gets called for them. Is there some class I can override, or some setting I can tweak, so the pane explicitly creates an instance of my custom label view, even for lines that consist solely of '\n' ?

Thanks for your help!

For reference, here's my code so far:

Here I override the EditorKit for the JTextPane:
    class WhitespaceEditorKit extends StyledEditorKit {
        public ViewFactory getViewFactory() {
            return new WhitespaceViewFactory();
        }
    }
Then I override the ViewFactory:
    class WhitespaceViewFactory implements ViewFactory {
        public View create(Element elem) {
            String kind = elem.getName();
            if (kind != null) {
                if (kind.equals(AbstractDocument.ContentElementName)) {
                    return new WhitespaceLabelView(elem);
                } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
                    return new ParagraphView(elem);
                } else if (kind.equals(AbstractDocument.SectionElementName)) {
                    return new BoxView(elem, View.Y_AXIS);
                } else if (kind.equals(StyleConstants.ComponentElementName)) {
                    return new ComponentView(elem);
                } else if (kind.equals(StyleConstants.IconElementName)) {
                    return new IconView(elem);
                }
            }
            // default to text display
            //return new LabelView(elem);
            return new WhitespaceLabelView(elem);
        }
    }
Finally, I override the LabelView's paint method, so I can paint over the whitespace. The \u007 are the Unicode characters I'm painting over the whitespace:
    class WhitespaceLabelView extends LabelView {
        public WhitespaceLabelView(Element elem) {
            super(elem);
        }
        
        public void paint(Graphics g, Shape a) {
            super.paint(g,a);
            
            //Here we give a visual representation of whitespace if the option is selected.
            if(showWhitespace) {
                java.awt.FontMetrics fontMetrics = g.getFontMetrics();
                String text = getText(getStartOffset(),getEndOffset()).toString();
                Rectangle alloc = (a instanceof Rectangle) ? (Rectangle)a : a.getBounds();
                int spaceWidth = fontMetrics.stringWidth(" ");
                int newlineWidth = fontMetrics.stringWidth("D");
                
                int sumOfTabs = 0;
                
                for(int i = 0; i < text.length(); i++) {
                    boolean isNewlinePostfixed = false;
                    if(text.substring(i,i+1).equals(" ")) {
                        int previousStringWidth = fontMetrics.stringWidth(text.substring(0,i)) + sumOfTabs;
                        //g.setColor(RBConstants.whitespaceHighlight);
                        //g.fillRect(alloc.x + previousStringWidth, alloc.y, spaceWidth, alloc.height);
                        g.setColor(Color.DARK_GRAY);
                        g.drawString("\u00b7",alloc.x+previousStringWidth,alloc.y+alloc.height-4);
                        
                    } else if (text.substring(i,i+1).equals("\t")) {
                        int previousStringWidth = fontMetrics.stringWidth(text.substring(0,i)) + sumOfTabs;
                        int tabWidth = (int)getTabExpander().nextTabStop((float)alloc.x+previousStringWidth,i) - previousStringWidth - alloc.x;
                        //g.setColor(RBConstants.tabColor);
                        //g.fillRect(alloc.x+previousStringWidth,alloc.y,tabWidth,alloc.height);
                        
                        g.setColor(Color.DARK_GRAY);
                        g.drawString(">",alloc.x+previousStringWidth+(tabWidth/2),alloc.y+alloc.height-4);
                        
                        sumOfTabs+=tabWidth;
                        
                    } else if (text.substring(i,i+1).equals("\n") || text.substring(i,i+1).equals("\r")) {
                        int previousStringWidth = fontMetrics.stringWidth(text.substring(0,i)) + sumOfTabs;
                        //g.setColor(Color.LIGHT_GRAY);
                        //g.fillRect(6+alloc.x+previousStringWidth,alloc.y,newlineWidth,alloc.height);
                        
                        g.setColor(Color.DARK_GRAY);
                        g.drawString("\u00b6",6+alloc.x+previousStringWidth,alloc.y+alloc.height-4);
                        

                    }
                }
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Feb 6 2007
Added on Jan 9 2007
6 comments
755 views