1

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

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

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

我以这种方式处理 KeyReleased:

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

这是一个例子:

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();
}
}
4

3 回答 3

1
于 2012-09-24T07:04:58.493 回答
0
  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);
    }
}

或者,我会使用 aDocumentListener而不是 a 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
}
于 2012-09-26T01:08:18.553 回答
0

我遇到了几乎相同的问题,我在其中突出显示并做了类似 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 来检索和修改插入符号的属性并删除突出显示属性。所以我更新了上面实现正确解决方案的代码。

于 2016-01-18T13:43:53.460 回答