首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JTextComponent :如何更新现有的StyledDocument元素

JTextComponent :如何更新现有的StyledDocument元素
EN

Stack Overflow用户
提问于 2017-07-07 20:48:26
回答 1查看 108关注 0票数 0

我使用两个DefaultStyledDocument编写了一个两个窗格的diff类。

现在,我想让用户在适当的位置更改用于显示删除和插入的颜色(以及,比如说,粗体),而不会重新区分或保留中间的比较结果。

我面临的问题是insertString会复制属性,所以我不能只在之后更新样式实例。

我尝试了DefaultStyledDocument.setLogicalStyle(int,Style),但在视觉上没有任何变化。

你有没有看到一种(简单/便宜)的方式来更新样式,而不需要重新创建整个文档?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-08 01:44:06

逻辑样式适用于整个段落。据我所知,没有办法将样式应用于段落中的字符,并让Swing自动侦听样式中的更改。

您可以做的是将样式用作常规的AttributeSet,然后使用ElementIterator扫描样式元素,因为样式的名称存储在AttributeSet.NameAttribute属性键下:

代码语言:javascript
运行
复制
void updateHighlight(StyledDocument doc,
                     AttributeSet newStyle) {

    Object styleName = newStyle.getAttribute(AttributeSet.NameAttribute);

    ElementIterator i = new ElementIterator(doc);
    for (Element e = i.first(); e != null; e = i.next()) {
        AttributeSet attr = e.getAttributes();
        Object name = attr.getAttribute(AttributeSet.NameAttribute);
        if (styleName.equals(name)) {
            int start = e.getStartOffset();
            int end = e.getEndOffset();
            doc.setCharacterAttributes(start, end - start,
                newStyle, false);
        }
    }
}

这是否符合“简单/便宜”的标准取决于你的决定。

下面是一个演示:

代码语言:javascript
运行
复制
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;

import javax.swing.Action;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;

import javax.swing.text.AttributeSet;
import javax.swing.text.Element;
import javax.swing.text.ElementIterator;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

public class StyleChanger {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> show());
    }

    private static final String HIGHLIGHT =
        StyleChanger.class.getName() + ".highlight";

    static void show() {
        JTextPane textPane = new JTextPane();

        Style normal = textPane.getStyle(StyleContext.DEFAULT_STYLE);
        Style highlight = textPane.addStyle(HIGHLIGHT, normal);
        StyleConstants.setBackground(highlight, Color.YELLOW);

        class Fragment {
            final AttributeSet style;
            final String text;

            Fragment(AttributeSet style,
                     String text) {
                this.style = style;
                this.text = text;
            }
        }

        Fragment[] fragments = {
            new Fragment(highlight, "Space"),
            new Fragment(normal, ": the final frontier.  These are the "),
            new Fragment(highlight, "voyages"),
            new Fragment(normal, " of the starship "),
            new Fragment(highlight, "Enterprise"),
            new Fragment(normal, ".  Its five-year "),
            new Fragment(highlight, "mission"),
            new Fragment(normal, ": to explore strange "),
            new Fragment(highlight, "new worlds"),
            new Fragment(normal, "; to seek out "),
            new Fragment(highlight, "new life"),
            new Fragment(normal, " and new civilizations; to "),
            new Fragment(highlight, "boldly go"),
            new Fragment(normal, " where no man has gone before!"),
        };

        for (Fragment fragment : fragments) {
            textPane.setCharacterAttributes(fragment.style, true);
            textPane.replaceSelection(fragment.text);
        }

        Action change = new AbstractAction("Change Highlight\u2026") {
            private static final long serialVersionUID = 1;

            @Override
            public void actionPerformed(ActionEvent event) {
                Color color = JColorChooser.showDialog(
                    textPane.getTopLevelAncestor(),
                    "Highlight Color",
                    textPane.getBackground());

                if (color != null) {
                    StyleConstants.setBackground(highlight, color);
                    updateHighlight(textPane.getStyledDocument(), highlight);
                }
            }
        };

        JButton changeButton = new JButton(change);

        JPanel buttonPane = new JPanel();
        buttonPane.add(changeButton);

        JFrame frame = new JFrame("Style Changer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(new JScrollPane(textPane));
        frame.getContentPane().add(buttonPane, BorderLayout.PAGE_END);

        frame.setSize(450, 300);
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private static void updateHighlight(StyledDocument doc,
                                        AttributeSet newStyle) {

        Object styleName = newStyle.getAttribute(AttributeSet.NameAttribute);

        ElementIterator i = new ElementIterator(doc);
        for (Element e = i.first(); e != null; e = i.next()) {
            AttributeSet attr = e.getAttributes();
            Object name = attr.getAttribute(AttributeSet.NameAttribute);
            if (styleName.equals(name)) {
                int start = e.getStartOffset();
                int end = e.getEndOffset();
                doc.setCharacterAttributes(start, end - start,
                    newStyle, false);
            }
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44971180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档