Перекрытие номеров разделителей в текстовом редакторе и маркер длинной строки

Я работаю над проектом по созданию текстового редактора (блокнот, в основном), в Swing и я столкнулся с проблемой с номерами строк. Я должен сказать, что я довольно новичок в Java, но я прилагаю все усилия, чтобы изменить это!

У вас есть ниже класса, который обрабатывает номера строк в JEditorPane Я использую. Но каждый раз, когда он добавляет еще одну цифру к номерам строк, я получаю двойную разделительную строку для ~10 строк текста. Как я могу предотвратить это?

Кроме того, как я могу добавить "Длинный маркер", просто еще одну линию, нарисованную примерно в 100 'm' символы слева.

Это скриншот, чтобы увидеть визуальный результат

Это класс:

/**
 * Part of the source code got from here:
 * developer.com/java/other/article.php/3318421/Add-Line-Numbering-in-the-JEditorPane.htm
 *
 * About the Author Stanislav Lapitsky is an offshore software developer and
 * consultant with more than 7 years of programming experience. His area of
 * knowledge includes java based technologies and RDBMS.
 *
 */
package MainGUI;

/**
 *
 * @author mrbigheart
 */
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;

public class LineNumbers {

    // private default constructor
    private LineNumbers() {
    }

    // private constructor
    private LineNumbers(JEditorPane edit) {
        edit.setEditorKit(new NumberedEditorKit());
    }

    // static factory
    public static LineNumbers valueOf(JEditorPane edit) {
        return new LineNumbers(edit);
    }

}

class NumberedEditorKit extends StyledEditorKit {

    @Override
    public ViewFactory getViewFactory() {
        return new NumberedViewFactory();
    }
}

class NumberedViewFactory implements ViewFactory {

    @Override
    public View create(Element elem) {
        String kind = elem.getName();
        if (kind != null) {
            switch (kind) {
                case AbstractDocument.ContentElementName:
                    return new LabelView(elem);
                case AbstractDocument.ParagraphElementName:
                    // return new ParagraphView(elem);
                    return new NumberedParagraphView(elem);
                case AbstractDocument.SectionElementName:
                    return new BoxView(elem, View.Y_AXIS);
                case StyleConstants.ComponentElementName:
                    return new ComponentView(elem);
                case StyleConstants.IconElementName:
                    return new IconView(elem);
            }
        }
        // default to text display
        return new LabelView(elem);
    }

}

final class NumberedParagraphView extends ParagraphView {

    public static short NUMBERS_WIDTH = 30;

    public NumberedParagraphView(Element e) {
        super(e);
        short top = 7;
        short left = 0;
        short bottom = 0;
        short right = 0;
        this.setInsets(top, left, bottom, right);
    }

    // indent for the JEditorPane
    @Override
    protected void setInsets(short top, short left, short bottom,
            short right) {
        super.setInsets(top, (short) (left + NUMBERS_WIDTH + 5),
                bottom, right);
    }

    @Override
    public void paintChild(Graphics g, Rectangle r, int n) {
        super.paintChild(g, r, n);
        View parent = this.getParent();
        int previousLineCount = getPreviousLineCount();
        int numberX = r.x - getLeftInset();
        int numberY = r.y + r.height - 5;

        //  Update sizes when number of digits in the line number changes
        int lines = getPreviousLineCount();
        int digits = Math.max(String.valueOf(lines).length(), 2);
        FontMetrics fontMetrics = g.getFontMetrics();
        //get the width of a zero character times the number of digits
        int width = (fontMetrics.charWidth('0') * digits) + numberX + 7;
        // update NUMBERS_WIDTH with the new width
        NUMBERS_WIDTH = (short)width;

        // line numbers rectangle (x, y, width, height)
        g.drawRect(0, 0, width, parent.getContainer().getHeight());
        g.setColor(Color.YELLOW);
        g.drawString(Integer.toString(previousLineCount + n + 1),
                numberX, numberY);
    }

    public int getPreviousLineCount() {
        int lineCount = 0;
        View parent = this.getParent();
        int count = parent.getViewCount();
        for (int i = 0; i < count; i++) {
            if (parent.getView(i) == this) {
                break;
            } else {
                lineCount += parent.getView(i).getViewCount();
            }
        }
        return lineCount;
    }
}

Заранее спасибо!

1 ответ

Решение

Это казалось улучшением для меня. Сделайте так, чтобы ширина и NUMBERS_WIDTH были максимальными, которых он когда-либо имел с Math.max() в paintChild ():

...

int width = (fontMetrics.charWidth('0') * digits) + numberX + 7;
// update NUMBERS_WIDTH with the new width
NUMBERS_WIDTH = (short) Math.max(NUMBERS_WIDTH, width);

// line numbers rectangle (x, y, width, height)
g.drawRect(0, 0, NUMBERS_WIDTH, parent.getContainer().getHeight());

...

Другие вопросы по тегам