本文目录导读:

在 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);
}
});
注意事项
- 文档类型:确保
JEditorPane已设置为text/html类型 - 段落检测:
getParagraphElement()返回当前光标所在的段落 - 属性重置:取消缩进时要考虑移除所有缩进属性,而不仅仅是减少数值
- 性能优化:对于大文档,建议只操作选中的部分
根据你的具体需求,选择最适合的实现方式,如果需要支持列表项的缩进控制,还需要额外处理 <ul> 和 <ol> 标签的样式。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播