6

我正在使用允许用户更改所选文本颜色的 JTextPane 创建一个文本编辑器。但是当用户选择文本,然后选择更改颜色的选项(例如,变为红色)时,文本不会显示为红色,直到取消选择文本。我尝试使用 setSelectedTextColor 来更改所选文本的颜色,但这不起作用,因为之后在任何时候选择文本时都会将文本更改为红色。有没有办法让选定的文本显示为实际颜色?Or like the way it works in Word where it's not the actual color of the text, but when text of different colors are selected they show up as different colors even when selected.

我使用以下代码来设置 JTextPane 和将所选文本更改为红色的按钮:

JButton redButton = new JButton(new StyledEditorKit.ForegroundAction("red", Color.RED));
redButton.setFocusable(false);
buttonPanel.add(redButton);

JTextPane 设置为内容类型 HTML 并使用 HTMLEditorKit:

p=new JTextPane();
p.setSize(300, 300);
kit = new HTMLEditorKit();
p.setEditorKit(kit);
p.setDocument(kit.createDefaultDocument());

p.setContentType("text/html");
p.setEditable(true);

如果您需要更多源代码来理解这个问题,请告诉我。谢谢你!

4

4 回答 4

5

看一下DefaultHighlightPainter内部类DefaultHighlighter

方法

    public void paint(Graphics g, int offs0, int offs1, Shape bounds, JTextComponent c) {
        Rectangle alloc = bounds.getBounds();
        try {
            // --- determine locations ---
            TextUI mapper = c.getUI();
            Rectangle p0 = mapper.modelToView(c, offs0);
            Rectangle p1 = mapper.modelToView(c, offs1);

            // --- render ---
            Color color = getColor();

            if (color == null) {
                g.setColor(c.getSelectionColor());
            }
            else {
                g.setColor(color);
            }

如您所见,它使用getColor()getSelectionColor()。您可以扩展类并调整高光绘画。

或者使用更简单的方法来覆盖您JTextPanegetSelectionColor(). 在该方法中,只需检查是否选择了文本并使用所选元素的属性来获得所需的 ccolor。如果未选择任何内容,则返回super.getSelectedColor()

更新:实际上应用颜色进行选择用于低级 GlyphView 的 public void paint(Graphics g, Shape a) { ... JTextComponent tc = (JTextComponent) c; 颜色 selFG = tc.getSelectedTextColor();

        if (// there's a highlighter (bug 4532590), and
            (tc.getHighlighter() != null) &&
            // selected text color is different from regular foreground
            (selFG != null) && !selFG.equals(fg)) {

            Highlighter.Highlight[] h = tc.getHighlighter().getHighlights();
            if(h.length != 0) {
                boolean initialized = false;
                int viewSelectionCount = 0;
                for (int i = 0; i < h.length; i++) {
                    Highlighter.Highlight highlight = h[i];
                    int hStart = highlight.getStartOffset();
                    int hEnd = highlight.getEndOffset();
                    if (hStart > p1 || hEnd < p0) {
                        // the selection is out of this view
                        continue;
                    }
                    if (!SwingUtilities2.useSelectedTextColor(highlight, tc)) {
                        continue;
                    }

...

如您所见,应用选择颜色与视图的默认颜色在 SwingUtilities2.useSelectedTextColor(highlight, tc) 中定义

在来源http://kickjava.com/src/com/sun/java/swing/SwingUtilities2.java.htm

 public static boolean useSelectedTextColor(Highlighter.Highlight  JavaDoc h, JTextComponent  JavaDoc c) {
     Highlighter.HighlightPainter  JavaDoc painter = h.getPainter();
     String  JavaDoc painterClass = painter.getClass().getName();
     if (painterClass.indexOf("javax.swing.text.DefaultHighlighter") != 0 &&
             painterClass.indexOf("com.sun.java.swing.plaf.windows.WindowsTextUI") != 0) {
         return false;
     }
     try {
         DefaultHighlighter.DefaultHighlightPainter  JavaDoc defPainter =
                 (DefaultHighlighter.DefaultHighlightPainter  JavaDoc) painter;
         if (defPainter.getColor() != null &&
                 !defPainter.getColor().equals(c.getSelectionColor())) {
             return false;
         }
     } catch (ClassCastException  JavaDoc e) {
         return false;
     }
     return true;
 }

所以使用颜色取决于L&F和画家。如果您定义 onw 画家,则不会使用颜色。

于 2013-10-01T05:26:23.397 回答
3

听起来您可能使用的不是字体系列名称。我重构了这个例子来使用JTextPane并看到了预期的结果。如那里所述,这些操作需要字体系列名称,例如默认值或,由嵌套在 中face=SansSerif的类指定。FontFamilyActionStyledEditorKit

图片

JTextPane textPane = new JTextPane();
于 2013-09-30T20:23:19.170 回答
0

更改所选文本颜色的最简单方法:

int start = textPane.getSelectionStart();
int end = textPane.getSelectionEnd();
int selectedLength = end - start;
StyleDocument style = pane.getStyledDocument();

//this give your attribute set of selected Text. 
AttributeSet oldSet = style.getCharacterElement(end-1).getAttributes();

//StyleContext for creating attribute set
StyleContext sc = StyleContext.getDefaultStyleContext();

// Attribute set which contains new color with old attributes
AttributeSet s = sc.addAttribute(oldSet, StyleConstants.Foreground, Color.RED);
//This set the color of the Text
style.setCharacterAttributes(start, selectedLength, s, true);
于 2017-07-14T12:49:44.200 回答
0

添加我的观点。这可能比上述方法更简单。

    JEditorPane ep = new JEditorPane() {
        @Override
        public Color getSelectionColor() {
            return COLOR_YOU_WANT;
        }

        @Override
        public Color getSelectedTextColor() {
            return COLOR_YOU_WANT;
        }
    };
于 2020-12-07T13:19:40.613 回答