在编写时更改 JTextPane 中的样式



我创建了一个具有两种不同样式的jtextpane:一种用于数字(粉红色前景),另一种用于其余样式(黑色前景)。我在 jtextpane 中添加了一个密钥侦听器(我使用 KeyRelease 函数)来处理新的按下字符,但我在编写过程中遇到了问题。方案如下:

  • 文字是:你好123
  • "
  • 你好"文本是黑色的,数字"123"是粉红色的。
  • 现在插入符号在"1"和"2"之间,我按"a"并出现一些奇怪的事情。
  • 字符"a"变为粉红色,然后变为黑色。

为什么它会在短时间内变黑?

我以这种方式处理密钥发布:

  1. 我用默认样式设置所有文本(清理阶段)
  2. 我将仅将前景更改为粉红色
  3. 的数字

这是一个例子:

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();
}
}
  • KeyListener 未指定用于 Swing JComponents,也不指定用于 JTextComponents

  • 对于 JTextComponent,您可以查看 DocumentListener

  • Oracle 教程包含带有样式文档的 JTextPane

  • 看看荧光笔

  1. 为什么会变黑?
    • 应该的。 1a2不是有效的整数。它会在短时间内变为粉红色,因为您的格式仅在事件之后发生。当您在粉红色字符之间书写时,您的文本将是粉红色的(直到您更改它)。

其他要点:

  • 由于您只需要格式化数字,因此无需将"默认"样式应用于已经"默认"的其他字符。
  • 在我的解决方案中,我按数字进行了。如果你想要整数(其中"1a2"为假),那么继续使用StringTokenizer。只要知道,如果句子末尾有一个数字,它就不会匹配 - I am 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);
    }
}

或者,我会使用DocumentListener而不是KeyListener.

public class SmartTextPane extends JTextPane implements DocumentListener{
    public SmartTextPane(){ 
        super();
        this.getDocument().addDocumentListener(this);
    }
    public void changedUpdate(DocumentEvent e){ 
        applyStyle();
    }
    public void insertUpdate(DocumentEvent e){} 
    public void removeUpdate(DocumentEvent e){}
    //define your style functions
}

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

我做了如下操作,它在文档过滤器中覆盖了 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 来检索和修改插入符号的属性并删除突出显示属性。所以我更新了上面的代码,实现了正确的解决方案。

相关内容

  • 没有找到相关文章

最新更新