文本编辑器分隔线号重叠和长线标记

Posted

技术标签:

【中文标题】文本编辑器分隔线号重叠和长线标记【英文标题】:Text editor separator line numbers overlap & long line marker 【发布时间】:2015-11-02 00:51:21 【问题描述】:

我正在开发一个在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;
    

提前谢谢你!

【问题讨论】:

我不会使用 JEditorPane 作为文本编辑器。 JEdi​​torPane 真正设计用于显示 html。您应该使用 JTextPane。您还可以查看可与文本窗格一起使用的Text Component Line Number。 【参考方案1】:

这对我来说似乎是一个进步。强制宽度和 NUMBERS_WIDTH 为它在paintChild() 中使用 Math.max() 时所达到的最大值:

...

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());

...

【讨论】:

这太棒了!它终于起作用了..感谢您的回复! ..如果您更友善,任何对长线标记的参考将不胜感激! :) .. 给我指出正确的方向就足够了!

以上是关于文本编辑器分隔线号重叠和长线标记的主要内容,如果未能解决你的问题,请参考以下文章

骑手 - 包长线

数据文件的内容中,字段中间用制表符Tab键分隔。

UITableViewController 中的键盘重叠文本字段

为什么Vim组装短线时应该打破长线?

怎样使用ABBYY finereader把PDF转成可编辑文件

Power BI Advanced编辑器如何获取SelectedRow的文本?