Java 在编写时更改JTextPane中的样式

Java 在编写时更改JTextPane中的样式,java,swing,styles,jtextpane,Java,Swing,Styles,Jtextpane,我创建了一个jtextpane,它有两种不同的样式:一种是数字样式(粉红色前景),另一种是默认样式(黑色前景)。我在jtextpane中添加了一个keylistener(我使用KeyReleased函数)来处理新按下的字符,但在编写过程中遇到了一个问题。情况如下: 文字是:你好123 “hello”文本为黑色,数字“123”为粉色 现在插入符号介于“1”和“2”之间,我按“a”时出现了一些奇怪的情况 角色“a”先变成粉红色,然后变成黑色 为什么它会在短时间内变黑 我以以下方式处理释放的钥匙:

我创建了一个jtextpane,它有两种不同的样式:一种是数字样式(粉红色前景),另一种是默认样式(黑色前景)。我在jtextpane中添加了一个keylistener(我使用KeyReleased函数)来处理新按下的字符,但在编写过程中遇到了一个问题。情况如下:

  • 文字是:你好123
  • “hello”文本为黑色,数字“123”为粉色
  • 现在插入符号介于“1”和“2”之间,我按“a”时出现了一些奇怪的情况
  • 角色“a”先变成粉红色,然后变成黑色
为什么它会在短时间内变黑

我以以下方式处理释放的钥匙:

  • 我将所有文本设置为默认样式(清除阶段)
  • 我将只为数字更改粉色前景

  • 例如:

    import java.awt.Color;
    import java.awt.event.KeyAdapter;
    import java.awt.event.KeyEvent;
    import java.util.StringTokenizer;
    
    import javax.swing.JFrame;
    import javax.swing.JTextPane;
    import javax.swing.text.Style;
    import javax.swing.text.StyleConstants;
    
    
    public class Example extends JFrame {
    
    JTextPane pn = new JTextPane();
    public Example() {
    
        addDefaultStyle(pn);
        addNumberStyle(pn);
    
        pn.addKeyListener(new KeyAdapter() {
    
            @Override
            public void keyReleased(KeyEvent arg0) {
                String text = pn.getText();
    
    
                pn.getStyledDocument().setCharacterAttributes(0, text.length(), pn.getStyle("default"), true);
    
                StringTokenizer ts = new StringTokenizer(text, " ");
    
                while(ts.hasMoreTokens()){
                    String token = ts.nextToken();
    
                    try{
                        Integer.parseInt(token);
    
                        pn.getStyledDocument().setCharacterAttributes(text.indexOf(token), token.length(), pn.getStyle("numbers"), true);
    
                    }catch(Exception e){
    
                        pn.getStyledDocument().setCharacterAttributes(text.indexOf(token), token.length(), pn.getStyle("default"), true);
                    }
                }
    
            }
        });
    
        getContentPane().add(pn);
        setSize(400, 400);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    
    private void addDefaultStyle(JTextPane pn){
        Style style = pn.addStyle("default", null);
    
        pn.setForeground(Color.blue);
        pn.setBackground(Color.WHITE);
    
        StyleConstants.setForeground(style, pn.getForeground());
        StyleConstants.setBackground(style, pn.getBackground());
        StyleConstants.setBold(style, false);
    }
    
    private void addNumberStyle(JTextPane pn){
        Style style = pn.addStyle("numbers", null);
    
        StyleConstants.setForeground(style, Color.PINK);
        StyleConstants.setBackground(style, Color.WHITE);
        StyleConstants.setBold(style, true);
    }
    
    public static void main(String args []){
        new Example();
    }
    }
    
    • 不是为Swing JComponents指定的,也不是为

    • 因为你已经看过了

    • Oracle教程包含

    • 看过

        • 不是为Swing JComponents指定的,也不是为

        • 因为你已经看过了

        • Oracle教程包含

        • 看过

      • 为什么会变成黑色?
        • 应该这样<代码>1a2不是有效的整数。它会在短时间内变为粉红色,因为只有在事件发生后才会进行格式化。当您在粉红色字符之间书写时,文本将为粉红色(直到您更改它)
      • 其他要点:

        • 因为您只需要格式化数字,所以不需要对已经是“默认”的其他字符应用“默认”样式
        • 在我的解决方案中,我是按数字计算的。如果您想要整数(其中“1a2”将为false),则继续使用StringTokenizer。只要知道如果句子末尾有一个数字,它就不会匹配-
          我是12。
        代码:

        public void keyReleased(KeyEvent arg0) {
            applyStyle();
        }
        
        public void applyStyle() {
            String text = pn.getText();
            pn.getStyledDocument().setCharacterAttributes(0, text.length(), pn.getStyle("default"), true);
        
            char[] textChar = text.toCharArray();
            for(int i=0, len=textChar.length; i<len; i++){
                if(Character.isDigit(textChar[i]))
                    pn.getStyledDocument().setCharacterAttributes(i, 1, pn.getStyle("numbers"), true);
            }
        }
        
      • 为什么会变成黑色?
        • 应该这样<代码>1a2不是有效的整数。它会在短时间内变为粉红色,因为只有在事件发生后才会进行格式化。当您在粉红色字符之间书写时,文本将为粉红色(直到您更改它)
      • 其他要点:

        • 因为您只需要格式化数字,所以不需要对已经是“默认”的其他字符应用“默认”样式
        • 在我的解决方案中,我是按数字计算的。如果您想要整数(其中“1a2”将为false),则继续使用StringTokenizer。只要知道如果句子末尾有一个数字,它就不会匹配-
          我是12。
        代码:

        public void keyReleased(KeyEvent arg0) {
            applyStyle();
        }
        
        public void applyStyle() {
            String text = pn.getText();
            pn.getStyledDocument().setCharacterAttributes(0, text.length(), pn.getStyle("default"), true);
        
            char[] textChar = text.toCharArray();
            for(int i=0, len=textChar.length; i<len; i++){
                if(Character.isDigit(textChar[i]))
                    pn.getStyledDocument().setCharacterAttributes(i, 1, pn.getStyle("numbers"), true);
            }
        }
        

        我几乎遇到了同样的问题,我做了突出显示和类似的事情
        inputTextDocModel.setCharacterAttributes(0,inputTextDocModel.getLength()+1,styleNormal,true)
        将突出显示的字符切换为正常字符。但是这个 实际上将应用于现有字符,但不应用于插入符号的属性。因此,新角色仍然显示为“突出显示”,尽管我已经将所有设置为“正常”

        我做了如下操作,在DocumentFilter中覆盖了replace()

        public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
                    throws BadLocationException {
         // styleNormal is the 'normal' Style, styleMarked is the 'highlighting' style
        
             inputTextDocModel.setCharacterAttributes(0, inputTextDocModel.getLength() + 1, styleNormal, true);
             super.replace(fb, offset, length, text, styleNormal.copyAttributes());
        
          // this is to make sure the caret update its style from 'highlighter' to 'normal' - 
          // assume variable 'editorkit' assigned as StyledEditorKit and has been assigned to the component 
          // by textcomponent.setEditorKit(editorkit)
        
             editorkit.getInputAttributes().removeAttributes(styleMarked.getAttributeNames());
        }
        
        我希望这个“解决方案”能有所帮助


        更新:实际上,我们可以简单地使用StyledEditorKit来检索和修改插入符号的属性,并删除突出显示属性。
        因此,我更新了上面的代码,实现了正确的解决方案。

        我遇到了几乎相同的问题,我做了突出显示和类似的事情
        inputTextDocModel.setCharacterAttributes(0,inputTextDocModel.getLength()+1,styleNormal,true)
        将突出显示的字符切换为正常字符。但是这个 实际上将应用于现有字符,但不应用于插入符号的属性。因此,新角色仍然显示为“突出显示”,尽管我已经将所有设置为“正常”

        我做了如下操作,在DocumentFilter中覆盖了replace()

        public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
                    throws BadLocationException {
         // styleNormal is the 'normal' Style, styleMarked is the 'highlighting' style
        
             inputTextDocModel.setCharacterAttributes(0, inputTextDocModel.getLength() + 1, styleNormal, true);
             super.replace(fb, offset, length, text, styleNormal.copyAttributes());
        
          // this is to make sure the caret update its style from 'highlighter' to 'normal' - 
          // assume variable 'editorkit' assigned as StyledEditorKit and has been assigned to the component 
          // by textcomponent.setEditorKit(editorkit)
        
             editorkit.getInputAttributes().removeAttributes(styleMarked.getAttributeNames());
        }
        
        我希望这个“解决方案”能有所帮助


        更新:实际上,我们可以简单地使用StyledEditorKit来检索和修改插入符号的属性,并删除突出显示属性。
        因此,我更新了上面的代码,实现了正确的解决方案。

        谢谢,我看到了您的链接,但我仍然有相同的问题。为什么如果我将文本的前景从粉红色更改为黑色,然后在文本中添加一个新字符,那么我“将有一个新字符为粉红色?”@Paul for better help Earth发布(非常简短且可运行)一个演示了您在文档、模式和HightLighteruse DocumentListener()方面的问题,放在那里好的,我将尝试使用document listener。谢谢,我看到了你的链接,但我仍然有同样的问题。为什么如果我将文本的前景从粉红色更改为黑色,然后在文本中添加一个新字符,我将有一个新字符为粉红色?@Paul为了获得更好的帮助,请尽快发布(非常简短且可运行)一篇演示了您在文档、模式和高亮显示方面的问题的文章使用DocumentListener(),放在那里好我将尝试使用Document listener。