如何在JTextPane中设置标签大小

时间:2018-09-15 18:42:18

标签: java swing jtextpane tabstop tab-size

我正在创建一个用Java编写的文本编辑器,并且我决定使用JTextPane而不是JTextArea,因为它将使我能够使用不同的配色方案创建富文本编辑。但是,JTextPane没有setTabSize(int size)函数,但是我可以使用TabStops和TabSet来实现此目的。

我的第一次尝试

    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.FontMetrics;

    import javax.swing.*;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.SimpleAttributeSet;
    import javax.swing.text.StyleConstants;
    import javax.swing.text.StyleContext;
    import javax.swing.text.TabSet;
    import javax.swing.text.TabStop;

    public class Editor extends JFrame {
        JTextPane txt;
        public Editor() {
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            RichTextEdit rte = new RichTextEdit();
            txt = new JTextPane(rte);
            txt.setPreferredSize(new Dimension(400,200));
            add(new JScrollPane(txt));

            Font f = new Font("Monospaced", Font.PLAIN, txt.getFont().getSize());
            txt.setFont(f);
            FontMetrics fm = txt.getFontMetrics(f);
            int width = fm.stringWidth("w");
            int tabSize = 4;

            TabStop[] tabs = new TabStop[1];
            tabs[0] = new TabStop(width*tabSize, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
            TabSet tabset = new TabSet(tabs);

            StyleContext cont = StyleContext.getDefaultStyleContext();
            AttributeSet a = cont.addAttribute(SimpleAttributeSet.EMPTY, 
StyleConstants.TabSet, tabset);
            txt.setParagraphAttributes(a, false);

            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    }

仅当光标位于文档开头时,此尝试才有效。如果我开始在JTextPane中键入内容,然后按Tab键,它只会上移到第4个位置。因此,如果我键入两个字母,则在按Tab键时,插入符号仅移动两个字符。然后在那之后,每按一次它只会移动一个字符。

第二次尝试: 我所做的就是添加另一个选项卡,只要我在一行上按两次Tab键即可,只要该行上没有其他字符,它就会起作用。基本上与我的第一次尝试相同,除了它允许按下两个制表符(等于8个字符)

TabStop[] tabs = new TabStop[2];
tabs[0] = new TabStop(width * tabSize, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
tabs[1] = new TabStop(width * tabSize * 2, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);

我必须将第二个制表符乘以2,才能使制表符空间移动另外4个字符。

我的最后一次尝试是能够获得给定行上的字符数。 (我已经完成了) 然后在该行中添加4个字符。因此,如果用户在JTextPane中键入:123456并按Tab,它将仅在末尾添加4个空格,但是在初始设置后尝试设置setParagraphAttributes时,我总是收到错误消息。因此,我的想法是它已经具有AttributeSet,然后更改值或删除AttributeSet,然后使用更新的TabSize添加它。这是我到目前为止的内容:

import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.Enumeration;

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.TabSet;
import javax.swing.text.TabStop;
import javax.swing.text.Utilities;

public class Editor extends JFrame {
    JTextPane txt;
    public Editor() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        RichTextEdit rte = new RichTextEdit();
        txt = new JTextPane(rte);
        txt.setPreferredSize(new Dimension(400,200));
        add(new JScrollPane(txt));
        txt.setFont(new Font("Monospaced", Font.PLAIN, 16));

        txt.addCaretListener(new CaretListener() {

            @Override
            public void caretUpdate(CaretEvent arg0) {
                // TODO Auto-generated method stub
                Update();
            }

        });

        Update();

        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void Update() {

        int caretPosition = txt.getCaretPosition();
        Element root = txt.getDocument().getDefaultRootElement();
        int n = root.getElementIndex(caretPosition) + 1;
        Element child = root.getElement(n-1);
        int start = child.getStartOffset();
        int end = child.getEndOffset();
        int length = end - start;
        int j = (length >0) ? length - 1 : 0;
        System.out.println(n);
        System.out.println(caretPosition);
        System.out.println(j);
        System.out.println("----------");

        Font f = new Font("Monospaced", Font.PLAIN, txt.getFont().getSize());
        FontMetrics fm = txt.getFontMetrics(f);
        int width = fm.stringWidth("w");
        int tabSize = (j > 0) ? j + 4 : 4;
        TabStop[] tabs = new TabStop[1];
        tabs[0] = new TabStop(width * tabSize, TabStop.ALIGN_LEFT, TabStop.LEAD_NONE);
        TabSet tabset = new TabSet(tabs);

        StyleContext cont = StyleContext.getDefaultStyleContext();
        AttributeSet a = cont.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.TabSet, tabset);
        txt.setParagraphAttributes(a, true);
    }
}

当我从caretListener调用更新函数时,在此行txt.setParagraphAttributes(a,true);处收到IllegalStateException

0 个答案:

没有答案