如果您想要整个段落框的背景被涂上,您需要一个自定义的ViewFactory
(因此提供它的自定义EditorKit
),它生成知道如何绘制自己背景的Box
/Paragraph
视图。
使用HTMLDocument
/HTMLEditorKit
,例如通过StyleSheet.getBoxPainter()
实现。
这是我针对DefaultStyledDocument
/StyledEditorKit
的解决方案:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Shape;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;
public class BoxBackgroundFactory implements ViewFactory {
private final ViewFactory viewFactory;
public BoxBackgroundFactory(ViewFactory viewFactory) {
this.viewFactory = viewFactory;
}
@Override
public View create(Element elem) {
String kind = elem.getName();
if (AbstractDocument.ParagraphElementName.equals(kind)) {
return new ParagraphView(elem);
} else if (AbstractDocument.SectionElementName.equals(kind)) {
return new BoxView(elem);
}
return viewFactory.create(elem);
}
@SuppressWarnings("serial")
public static StyledEditorKit newEditorKit() {
return new StyledEditorKit() {
private final BoxBackgroundFactory boxbgFactory =
new BoxBackgroundFactory(super.getViewFactory());
@Override public ViewFactory getViewFactory() {
return boxbgFactory;
}
};
}
static void paintBackground(View view, Graphics g, Shape a) {
Color bg = null;
AttributeSet atts = view.getAttributes();
if (atts.isDefined(StyleConstants.Background)) {
bg = (Color) atts.getAttribute(StyleConstants.Background);
} else {
AttributeSet linked = atts.getResolveParent();
if (linked instanceof Style)
bg = (Color) linked.getAttribute(StyleConstants.Background);
}
if (bg == null) return;
Rectangle rect = (a instanceof Rectangle) ? (Rectangle) a : a.getBounds();
g.setColor(bg);
g.fillRect(rect.x, rect.y, rect.width, rect.height);
}
private static class BoxView extends javax.swing.text.BoxView {
BoxView(Element elem) {
super(elem, View.Y_AXIS);
}
@Override
public void paint(Graphics g, Shape a) {
paintBackground(this, g, a);
super.paint(g, a);
}
}
private static class ParagraphView extends javax.swing.text.ParagraphView {
ParagraphView(Element elem) {
super(elem);
}
@Override
public void paint(Graphics g, Shape a) {
paintBackground(this, g, a);
super.paint(g, a);
}
}
}
这是一个使用它的演示(与其他几个建议进行比较):
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
@SuppressWarnings("serial")
public class BoxBackgroundDemo extends JFrame {
BoxBackgroundDemo() {
super("Box background demo");
super.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
JTextPane editor = new JTextPane();
editor.setEditorKit(BoxBackgroundFactory.newEditorKit());
StyledDocument document = editor.getStyledDocument();
Style defaultStyle = document.getStyle(StyleContext.DEFAULT_STYLE);
StyleConstants.setSpaceAbove(defaultStyle, 5f);
StyleConstants.setSpaceBelow(defaultStyle, 5f);
Style highlight = document.addStyle("hilite", defaultStyle);
StyleConstants.setBackground(highlight, Color.RED);
StyleConstants.setForeground(highlight, Color.YELLOW);
String paragraph = "The quick brown fox jumps over the lazy fox. 1234567890\n";
try {
document.insertString(0, paragraph, null);
document.insertString(document.getLength(), paragraph, null);
document.setCharacterAttributes(paragraph.length() / 2,
paragraph.length(), highlight, false);
document.insertString(document.getLength(), paragraph, null);
document.insertString(document.getLength(), paragraph, null);
document.setParagraphAttributes(paragraph.length() * 5 / 2,
paragraph.length(), highlight, false);
document.insertString(document.getLength(), paragraph, null);
document.insertString(document.getLength(), paragraph, null);
editor.getHighlighter().addHighlight(
paragraph.length() * 9 / 2, paragraph.length() * 11 / 2,
new DefaultHighlighter.DefaultHighlightPainter(Color.RED));
document.insertString(document.getLength(), paragraph, null);
document.setLogicalStyle(paragraph.length() * 6, highlight);
} catch (BadLocationException e) {
e.printStackTrace();
}
super.add(new JScrollPane(editor));
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(() -> {
BoxBackgroundDemo window = new BoxBackgroundDemo();
window.pack();
window.setLocationRelativeTo(null);
window.setVisible(true);
});
}
}
![demo](https://istack.dev59.com/sPWHC.webp)
在我看来,为此目的编写自定义
highlight
绘制实现是最不合适的方法。
Highlighter.HighlightPainter
来供JTextComponent
的Highlighter
使用,以实现此功能。 - Evgeni Sergeev