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