我创建了一个具有两种不同样式的jtextpane:一种用于数字(粉红色前景),另一种用于其余样式(黑色前景)。我在 jtextpane 中添加了一个密钥侦听器(我使用 KeyRelease 函数)来处理新的按下字符,但我在编写过程中遇到了问题。方案如下:
- 文字是:你好123 "
- 你好"文本是黑色的,数字"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();
}
}
-
KeyListener 未指定用于 Swing JComponents,也不指定用于 JTextComponents
-
对于 JTextComponent,您可以查看 DocumentListener
-
Oracle 教程包含带有样式文档的 JTextPane
-
看看荧光笔
- 为什么会变黑?
- 应该的。
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 来检索和修改插入符号的属性并删除突出显示属性。所以我更新了上面的代码,实现了正确的解决方案。