• Post Reply Bookmark Topic Watch Topic
  • New Topic

Dynamically change text attribute or font in JTextPane, backspace issue with setCharacterAttribute?

 
bean ryu
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello people, I am writing a Java GUI that checks for unmatched parenthesis and underlines them. Bascially, I have a textPane and a thread that runs everytime the user presses the "(", ")", backspace or delete key. Something like what Eclipse has.

This code correctly underlines all the unmatched parenthesis so far, but it has a problem.
Let say at the beginning I have a empty textpane,

I type in a '('

textpane shows '(' with a red underline.

I type in a 'b'

textpane shows '(b' with only '(' underlined

now I type in a backspace

textpane shows '(' with only '(' underline

now I type in 'b' again

textpane shows '(b' with BOTH underlined... this is not what I want, I want only '(' underlined, can anyone show me a way to do this? I am using the setCharacterAttribute method, but it seems it doesn't work with backspace, whenever I backspace and the cursors moves to the right of a underlined character, every character I type in after that underlined character will always have the same style as that character.

here is my code:

public void Run(){
...
Stack<Integer> unmatchedList = checkForError(parenthesis);

for(Integer i : unmatchedList){
textpane.getStyledDocument().setCharacterAttributes(i, 1, red_underline, true);
}
...
}

// parenthesis has position of a '(' or ')' as key and a integer as value, a value of 0 = '(' and 1 = ')'
private Stack<Integer> checkForError(TreeMap<Integer, Integer> parenthesis){

Stack<Integer> un_r = new Stack<Integer>();// list of unmatched ')'
Stack<Integer> un_l = new Stack<Integer>();// list of unmatched '('

for(Integer i : parenthesis.keySet()){
// right
if(parenthesis.get(i) == 1){
if(un_l.isEmpty()){
un_r.push(i);
} else {
int l_p = un_l.pop();
ta.getStyledDocument().setCharacterAttributes(l_p, 1, defaultStyle, true);
int r_p = i;
ta.getStyledDocument().setCharacterAttributes(r_p, 1, defaultStyle, true);
}
}
// left
else if(parenthesis.get(i) == 0){
un_l.push(i);
}
}
un_r.addAll(un_l);

return un_r;
}

I really appreciate your inputs!!
 
Rob Camick
Ranch Hand
Posts: 2700
10
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Please use the "code" tags when posting code so it is readable.



I don't think you want to use "true".
 
bean ryu
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I tried using false in the setCharacterAttribute method, but it only causes the new style not overriding the old one, the backspace issue still persists.

Sorry about not using the code tag.
 
Stanislav Lapitsky
Ranch Hand
Posts: 53
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all I would recommend to use Highlighter and highlight to show the cases. Changin attributes isn't very good. It's slower and add edits in Undo sequence.
For your case I would add input attribute clearing. Get the EditorKit and cast it to StyledEditorKit. Then get InputAttributes. In the attributes just remove the underline attribute. You can do this on each caret update. Or use a smarter algorithm to clear the attribute on backspace/delete.

Regards,
Stas
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!