JTextPane中的多色文本选择(Swing) [英] Multi-color text selection in JTextPane (Swing)
问题描述
我有一个JTextPane,其样式为Docuent.我以编程方式插入了文本:"Hello World".单词"Hello"是红色,单词"World"是绿色.有什么办法可以选择两个单词,选择矩形变成半红色半绿色(或所选字符的颜色)吗?通过选择,我的意思是在运行时而不是通过编程方式选择文本...
I have a JTextPane, with styledDocuent. I've inserted programmatically the text: "Hello World". Word "Hello" is red, and word "World" is green. Is there any way I can select the two words, and the selection rectangle becomes half red half green(or whatever color the selected character is)? By select, I mean, select text at runtime, not programmatically...
我相信在更改jTextPane中选定文本的颜色, StanislavL告诉我如何实现,因为我不知道如何实现.
I believe here Changing color of selected text in jTextPane , StanislavL tells how this can be achieved, by I don't know how to implement it.
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);
}
推荐答案
查看是否足以满足您的需求.也许有更好的方法,但是它可以与您的示例一起使用.
See if this is good enough for what you need. There is probably a better way to do it, but it works with your example.
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
方法(其中有些是从源代码复制粘贴).
I create and set a new Highlighter
which keeps hold of the colors for each offset range in the document. It also has its own LayeredHighlighter.LayerPainter
where I partially override the paintLayer
method (some of it is copy-paste from the source).
Interval
类只是一个帮助实用程序,您可以删除它并在突出显示机制中添加其功能.
The Interval
class is just a help utility, you can remove it and add its functionality inside the highlighting mechanism instead.
这篇关于JTextPane中的多色文本选择(Swing)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!