JEditorPaneHTMLEditorKitParserUnindent取消缩进

wen java案例 2

本文目录导读:

JEditorPaneHTMLEditorKitParserUnindent取消缩进

  1. 方案一:使用 MutableAttributeSet 修改段落边距
  2. 方案二:通过 HTML 样式标签实现
  3. 方案三:完整的缩进/取消缩进工具类
  4. 使用示例
  5. 注意事项

JEditorPane 中使用 HTMLEditorKit 实现“取消缩进”(Unindent)功能,通常需要操作文档的 段落属性,以下是几种实现方案:

使用 MutableAttributeSet 修改段落边距

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
public void unindent(JEditorPane editor) {
    HTMLDocument doc = (HTMLDocument) editor.getDocument();
    Element paragraph = doc.getParagraphElement(editor.getCaretPosition());
    // 获取当前段落属性
    AttributeSet currentAttrs = paragraph.getAttributes();
    MutableAttributeSet newAttrs = new SimpleAttributeSet(currentAttrs);
    // 获取当前的左缩进(CSS padding-left 或 margin-left)
    int currentIndent = 0;
    Object paddingLeft = currentAttrs.getAttribute(CSS.Attribute.PADDING_LEFT);
    if (paddingLeft != null) {
        try {
            currentIndent = Integer.parseInt(paddingLeft.toString().replace("px", ""));
        } catch (NumberFormatException e) {
            currentIndent = 0;
        }
    }
    // 减少缩进(每次减少20像素,最小为0)
    int newIndent = Math.max(0, currentIndent - 20);
    // 设置新的缩进
    if (newIndent > 0) {
        newAttrs.addAttribute(CSS.Attribute.PADDING_LEFT, newIndent + "px");
    } else {
        newAttrs.removeAttribute(CSS.Attribute.PADDING_LEFT);
    }
    // 应用更改
    doc.setParagraphAttributes(0, doc.getLength(), newAttrs, true);
}

通过 HTML 样式标签实现

public void unindentWithStyle(JEditorPane editor) {
    HTMLDocument doc = (HTMLDocument) editor.getDocument();
    try {
        // 获取选中文本或光标所在段落
        int start = editor.getSelectionStart();
        int end = editor.getSelectionEnd();
        if (start == end) {
            // 没有选择,操作当前段落
            Element para = doc.getParagraphElement(start);
            start = para.getStartOffset();
            end = para.getEndOffset();
        }
        // 构造取消缩进的 HTML 片段
        String unindentHTML = "<p style='margin-left: 0px'>";
        // 这里可以使用更复杂的逻辑来处理整个段落
        // 替换选中的文本
        doc.replace(start, end - start, unindentHTML, 
                    null);
    } catch (BadLocationException e) {
        e.printStackTrace();
    }
}

完整的缩进/取消缩进工具类

import javax.swing.text.*;
import javax.swing.text.html.*;
import java.awt.event.*;
public class IndentManager {
    private static final int INDENT_STEP = 20; // 每次缩进像素
    public static void indent(JEditorPane editor) {
        modifyIndent(editor, INDENT_STEP);
    }
    public static void unindent(JEditorPane editor) {
        modifyIndent(editor, -INDENT_STEP);
    }
    private static void modifyIndent(JEditorPane editor, int delta) {
        HTMLDocument doc = (HTMLDocument) editor.getDocument();
        int start = editor.getSelectionStart();
        int end = editor.getSelectionEnd();
        if (start == end) {
            // 无选择,操作当前段落
            Element para = doc.getParagraphElement(start);
            start = para.getStartOffset();
            end = para.getEndOffset();
        }
        try {
            // 获取段落文本
            String paragraphText = doc.getText(start, end - start);
            // 计算新的缩进
            int currentIndent = getCurrentIndent(doc, start);
            int newIndent = Math.max(0, currentIndent + delta);
            // 应用到该段落
            MutableAttributeSet attrs = new SimpleAttributeSet();
            if (newIndent > 0) {
                attrs.addAttribute(CSS.Attribute.MARGIN_LEFT, newIndent + "px");
            }
            doc.setParagraphAttributes(start, end - start, attrs, false);
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }
    private static int getCurrentIndent(HTMLDocument doc, int offset) {
        Element para = doc.getParagraphElement(offset);
        AttributeSet attrs = para.getAttributes();
        Object marginLeft = attrs.getAttribute(CSS.Attribute.MARGIN_LEFT);
        if (marginLeft != null) {
            try {
                return Integer.parseInt(marginLeft.toString().replace("px", ""));
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        return 0;
    }
}

使用示例

// 在 Action 中调用
JEditorPane editor = new JEditorPane();
editor.setContentType("text/html");
editor.setText("<p>This is a test paragraph</p>");
// 绑定快捷键 Ctrl+Shift+M
editor.getInputMap().put(
    KeyStroke.getKeyStroke(KeyEvent.VK_M, 
                           InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK),
    "unindent"
);
editor.getActionMap().put("unindent", new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        IndentManager.unindent(editor);
    }
});

注意事项

  1. 文档类型:确保 JEditorPane 已设置为 text/html 类型
  2. 段落检测getParagraphElement() 返回当前光标所在的段落
  3. 属性重置:取消缩进时要考虑移除所有缩进属性,而不仅仅是减少数值
  4. 性能优化:对于大文档,建议只操作选中的部分

根据你的具体需求,选择最适合的实现方式,如果需要支持列表项的缩进控制,还需要额外处理 <ul><ol> 标签的样式。

抱歉,评论功能暂时关闭!