我有一个带有styledDocuent的JTextPane。我已经通过编程方式插入了文本:" Hello World"。 Word"你好"是红色的,和#34;世界"是绿色的。有什么方法可以选择这两个单词,选择矩形会变成半红半绿(或者所选字符的颜色是什么)?通过选择,我的意思是,在运行时选择文本,而不是以编程方式...
我相信Changing color of selected text in jTextPane,StanislavL讲述了如何实现这一点,我不知道如何实现它。
修改:
SimpleAttributeSet aset = new SimpleAttributeSet();
StyleConstants.setForeground(aset, Color.RED);
muTextPane.setCharacterAttributes(aset, false);
try {
muTextPane.getStyledDocument().insertString(muTextPane.getCaretPosition(), "Hello", aset);
muTextPane.setCaretPosition(muTextPane.getStyledDocument().getLength());
} catch (BadLocationException ex) {
Logger.getLogger(View1.class.getName()).log(Level.SEVERE, null, ex);
}
StyleConstants.setForeground(aset, Color.GREEN);
muTextPane.setCharacterAttributes(aset, false);
try {
muTextPane.getStyledDocument().insertString(muTextPane.getCaretPosition(), " World", aset);
muTextPane.setCaretPosition(muTextPane.getStyledDocument().getLength());
} catch (BadLocationException ex) {
Logger.getLogger(View1.class.getName()).log(Level.SEVERE, null, ex);
}
答案 0 :(得分:2)
看看这是否足以满足您的需求。可能有更好的方法,但它适用于您的示例。
public class ColorTextPane extends JFrame {
static JTextPane muTextPane = new JTextPane();
public static void main(String[] args) {
new ColorTextPane();
}
public ColorTextPane() {
///// Code from the question /////
SimpleAttributeSet aset = new SimpleAttributeSet();
StyleConstants.setForeground(aset, Color.RED);
StyleConstants.setFontSize(aset, 14);
muTextPane.setCharacterAttributes(aset, false);
try {
muTextPane.getStyledDocument().insertString(muTextPane.getCaretPosition(), "Hello", aset);
muTextPane.setCaretPosition(muTextPane.getStyledDocument().getLength());
} catch (BadLocationException ex) {
ex.printStackTrace();
}
StyleConstants.setForeground(aset, Color.GREEN);
muTextPane.setCharacterAttributes(aset, false);
try {
muTextPane.getStyledDocument().insertString(muTextPane.getCaretPosition(), " World", aset);
muTextPane.setCaretPosition(muTextPane.getStyledDocument().getLength());
} catch (BadLocationException ex) {
ex.printStackTrace();
}
///// End code from the question /////
muTextPane.setHighlighter(new MyHighlighter());
add(muTextPane);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
private static class MyHighlighter extends DefaultHighlighter {
private static List<Interval> ranges = new ArrayList<>();
private static Map<Interval, Color> rangesColors = new HashMap<>();
private static LayeredHighlighter.LayerPainter DefaultPainter = new MyDHP(null);
@Override
public Object addHighlight(int p0, int p1, HighlightPainter p) throws BadLocationException {
return super.addHighlight(p0, p1, DefaultPainter);
}
@Override
public void removeHighlight(Object tag) {
super.removeHighlight(tag);
ranges.clear();
rangesColors.clear();
}
private static class MyDHP extends DefaultHighlightPainter {
public MyDHP(Color arg0) {
super(arg0);
}
@Override
public Shape paintLayer(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c, View view) {
Rectangle r;
if (offs0 == view.getStartOffset() && offs1 == view.getEndOffset()) {
// Contained in view, can just use bounds.
if (bounds instanceof Rectangle)
r = (Rectangle) bounds;
else
r = bounds.getBounds();
}
else {
// Should only render part of View.
try {
// --- determine locations ---
Shape shape = view.modelToView(offs0, Position.Bias.Forward,
offs1,Position.Bias.Backward, bounds);
r = (shape instanceof Rectangle) ? (Rectangle)shape : shape.getBounds();
} catch (BadLocationException e) {
// can't render
r = null;
}
}
if (r != null) {
// If we are asked to highlight, we should draw something even
// if the model-to-view projection is of zero width (6340106).
r.width = Math.max(r.width, 1);
// Override simple fillRect
Interval newInt = new Interval(offs0, offs1);
for (Interval interval : ranges) {
if (interval.semiIncludes(newInt)) {
g.setColor(rangesColors.get(interval));
g.fillRect(r.x, r.y, r.width, r.height);
return r;
}
}
ranges.add(newInt);
rangesColors.put(newInt, getColor());
g.setColor(rangesColors.get(newInt));
g.fillRect(r.x, r.y, r.width, r.height);
}
return r;
}
@Override
public Color getColor() {
return StyleConstants.getForeground(muTextPane.getCharacterAttributes());
}
}
}
}
class Interval {
int start;
int end;
Interval(int p0, int p1) {
start = Math.min(p0, p1);
end = Math.max(p0, p1);
}
boolean semiIncludes(Interval intv) {
if (intv.start == this.start || intv.end == this.end)
return true;
return false;
}
}
我创建并设置了一个新的Highlighter
,它保留了文档中每个偏移范围的颜色。它也有自己的LayeredHighlighter.LayerPainter
,我部分覆盖了paintLayer
方法(其中一些是来自源的复制粘贴)。
Interval
类只是一个帮助实用程序,您可以将其删除并在突出显示机制中添加其功能。