001    package nl.cwi.sen1.gui.plugin.editor;
002    
003    import java.awt.Graphics;
004    import java.awt.Rectangle;
005    
006    import javax.swing.text.AbstractDocument;
007    import javax.swing.text.BoxView;
008    import javax.swing.text.ComponentView;
009    import javax.swing.text.Element;
010    import javax.swing.text.IconView;
011    import javax.swing.text.LabelView;
012    import javax.swing.text.ParagraphView;
013    import javax.swing.text.StyleConstants;
014    import javax.swing.text.View;
015    import javax.swing.text.ViewFactory;
016    
017    class NumberedEditorKit extends EditorKit {
018        private static final ViewFactory defaultFactory = new NumberedViewFactory();
019    
020        public NumberedEditorKit() {
021            super();
022        }
023    
024        public ViewFactory getViewFactory() {
025            return defaultFactory;
026        }
027    
028        static class NumberedViewFactory implements ViewFactory {
029            public View create(Element elem) {
030                String kind = elem.getName();
031                if (kind != null)
032                    if (kind.equals(AbstractDocument.ContentElementName)) {
033                        return new LabelView(elem);
034                    } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
035                        // return new ParagraphView(elem);
036                        return new NumberedParagraphView(elem);
037                    } else if (kind.equals(AbstractDocument.SectionElementName)) {
038                        return new BoxView(elem, View.Y_AXIS);
039                    } else if (kind.equals(StyleConstants.ComponentElementName)) {
040                        return new ComponentView(elem);
041                    } else if (kind.equals(StyleConstants.IconElementName)) {
042                        return new IconView(elem);
043                    }
044                // default to text display
045                return new LabelView(elem);
046            }
047        }
048    
049        static class NumberedParagraphView extends ParagraphView {
050            public static short NUMBERS_WIDTH = 25;
051    
052            public NumberedParagraphView(Element e) {
053                super(e);
054                short top = 0;
055                short left = 0;
056                short bottom = 0;
057                short right = 0;
058                this.setInsets(top, left, bottom, right);
059            }
060    
061            protected void setInsets(short top, short left, short bottom,
062                    short right) {
063                super.setInsets(top, (short) (left + NUMBERS_WIDTH), bottom, right);
064            }
065    
066            public void paintChild(Graphics g, Rectangle r, int n) {
067                super.paintChild(g, r, n);
068                int previousLineCount = getPreviousLineCount();
069                int numberX = r.x - getLeftInset();
070                int numberY = r.y + r.height - 5;
071                g.drawString(Integer.toString(previousLineCount + n + 1), numberX,
072                        numberY);
073            }
074    
075            public int getPreviousLineCount() {
076                int lineCount = 0;
077                View parent = this.getParent();
078                int count = parent.getViewCount();
079                for (int i = 0; i < count; i++) {
080                    if (parent.getView(i) == this) {
081                        break;
082                    }
083                    lineCount += parent.getView(i).getViewCount();
084                }
085                return lineCount;
086            }
087        }
088    }