JTextPane中的多色文本选择(Swing) [英] Multi-color text selection in JTextPane (Swing)

查看:108
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆