Problem extending DefaultStyleDocument--insertString jumps caret to end of document

Thread Solved

Join Date: Jun 2008
Posts: 408
Reputation: sciwizeh is on a distinguished road 
Solved Threads: 22
sciwizeh's Avatar
sciwizeh sciwizeh is offline Offline
Posting Pro in Training

Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #1
Mar 16th, 2009
Hello All,
I'm trying to write a simple html editor that will highlight tags, and it does, but if the user types the caret jumps to the very end of the document, how can I stop this from happening?
here's my code:
  1. import javax.swing.*;
  2.  
  3. /**
  4.  * Main frame for the program.
  5.  * @author Bill
  6.  *
  7.  */
  8. public class MainFrame extends JFrame {
  9. private static final long serialVersionUID = -7853618434340029314L;
  10. JTextPane editor = new JTextPane();
  11. SyntaxDocument2 sd = new SyntaxDocument2();
  12. /**
  13.   * Make a main frame.
  14.   */
  15. public MainFrame() {
  16. this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
  17. this.setSize( 500, 500 );
  18. editor.setDocument( sd );
  19. this.add( editor );
  20. this.setVisible( true );
  21. }
  22. /**
  23.   * entry point of the program
  24.   * @param args command line arguments
  25.   */
  26. public static void main(String[] args) {
  27. new MainFrame();
  28. }
  29. }
  1. /**
  2.  *
  3.  */
  4. import java.awt.Color;
  5.  
  6. import javax.swing.text.AttributeSet;
  7. import javax.swing.text.BadLocationException;
  8. import javax.swing.text.DefaultStyledDocument;
  9. import javax.swing.text.SimpleAttributeSet;
  10. import javax.swing.text.StyleConstants;
  11.  
  12.  
  13. /**
  14.  * @author Bill
  15.  *
  16.  */
  17. public class SyntaxDocument2 extends DefaultStyledDocument {
  18. private static final long serialVersionUID = 8802669064394912853L;
  19. SimpleAttributeSet norm = new SimpleAttributeSet();
  20. SimpleAttributeSet tag = new SimpleAttributeSet();
  21. SimpleAttributeSet string = new SimpleAttributeSet();
  22. /**
  23.   * Sets some stuff up.
  24.   */
  25. public SyntaxDocument2() {
  26. StyleConstants.setForeground( tag, Color.green );
  27. StyleConstants.setForeground( string, Color.red );
  28. }
  29. /**
  30.   * @see javax.swing.text.AbstractDocument#insertString(int, java.lang.String, javax.swing.text.AttributeSet)
  31.   */
  32. @Override
  33. public void insertString( int offs, String str, AttributeSet a )
  34. throws BadLocationException {
  35. super.insertString( offs, str, a );
  36.  
  37. String str2 = super.getText( 0, super.getLength() );
  38.  
  39. super.remove( 0, super.getLength() );
  40.  
  41. int off = 0;
  42. char c;
  43. boolean inTag=false;
  44. boolean inString=false;
  45. for(int i = 0;i<str2.length();i++,off++) {
  46. c=str2.charAt( i );
  47.  
  48. switch( c ) {
  49. case '<':
  50. inTag=true;
  51. super.insertString( off, ""+c, tag );
  52. break;
  53. case '>':
  54. inTag=false;
  55. super.insertString( off, ""+c, tag );
  56. break;
  57. case '"':
  58. if(inTag) {
  59. inString=!inString;
  60. super.insertString( off, ""+c, string );
  61. } else {
  62. super.insertString( off, ""+c, norm );
  63. }
  64. break;
  65. default:
  66. if(inTag) {
  67. if(inString) {
  68. super.insertString( off, ""+c, string );
  69. } else {
  70. super.insertString( off, ""+c, tag );
  71. }
  72. } else {
  73. super.insertString( off, ""+c, norm );
  74. }
  75. break;
  76. }
  77. }
  78. }
  79. }
My site, random PM's from people I haven't hear from before will be DELETED
"If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed.",
"If we knew what it was we were doing, it would not be called research, would it? "
-Albert Einstein
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 54
Reputation: Intrade is an unknown quantity at this point 
Solved Threads: 5
Intrade Intrade is offline Offline
Junior Poster in Training

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #2
Mar 17th, 2009
This may be a sloppy method of doing so, but you can send a reference to the JTextPane that you are using and manipulate the Caret after you are done sending characters to the Document.

  1. import javax.swing.*;
  2.  
  3. /**
  4.  * Main frame for the program.
  5.  * @author Bill
  6.  *
  7.  */
  8. public class MainFrame extends JFrame {
  9. private static final long serialVersionUID = -7853618434340029314L;
  10. JTextPane editor = null;
  11. SyntaxDocument2 sd = null;
  12.  
  13. /**
  14.   * Make a main frame.
  15.   */
  16. public MainFrame() {
  17. this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
  18. editor = new JTextPane();
  19. sd = new SyntaxDocument2( editor );
  20. this.setSize( 500, 500 );
  21. editor.setDocument( sd );
  22. this.add( editor );
  23. this.setVisible( true );
  24. }
  25.  
  26. /**
  27.   * entry point of the program
  28.   * @param args command line arguments
  29.   */
  30. public static void main(String[] args) {
  31. new MainFrame();
  32. }
  33. }

  1. /**
  2.  *
  3.  */
  4. import java.awt.Color;
  5.  
  6. import javax.swing.JTextPane;
  7. import javax.swing.text.AttributeSet;
  8. import javax.swing.text.BadLocationException;
  9. import javax.swing.text.DefaultStyledDocument;
  10. import javax.swing.text.SimpleAttributeSet;
  11. import javax.swing.text.StyleConstants;
  12.  
  13.  
  14. /**
  15.  * @author Bill
  16.  *
  17.  */
  18. public class SyntaxDocument2 extends DefaultStyledDocument {
  19. private static final long serialVersionUID = 8802669064394912853L;
  20. SimpleAttributeSet norm = new SimpleAttributeSet();
  21. SimpleAttributeSet tag = new SimpleAttributeSet();
  22. SimpleAttributeSet string = new SimpleAttributeSet();
  23. private JTextPane jp = null; // A reference to a JTextPane
  24.  
  25. /**
  26.   * Sets some stuff up.
  27.   */
  28. public SyntaxDocument2( JTextPane jp ) {
  29. this.jp = jp; // assigning the passed reference to the globally scoped one
  30. StyleConstants.setForeground( tag, Color.green );
  31. StyleConstants.setForeground( string, Color.red );
  32. }
  33. /**
  34.   * @see javax.swing.text.AbstractDocument#insertString(int, java.lang.String, javax.swing.text.AttributeSet)
  35.   */
  36. @Override
  37. public void insertString( int offs, String str, AttributeSet a )
  38. throws BadLocationException {
  39. super.insertString( offs, str, a );
  40.  
  41. String str2 = super.getText( 0, super.getLength() );
  42.  
  43.  
  44. super.remove( 0, super.getLength() );
  45.  
  46. int off = 0;
  47. char c;
  48. boolean inTag=false;
  49. boolean inString=false;
  50. for(int i = 0;i<str2.length();i++,off++) {
  51. c=str2.charAt( i );
  52.  
  53. switch( c ) {
  54. case '<':
  55. inTag=true;
  56. super.insertString( off, ""+c, tag );
  57. break;
  58. case '>':
  59. inTag=false;
  60. super.insertString( off, ""+c, tag );
  61. break;
  62. case '"':
  63. if(inTag) {
  64. inString=!inString;
  65. super.insertString( off, ""+c, string );
  66. } else {
  67. super.insertString( off, ""+c, norm );
  68. }
  69. break;
  70. default:
  71. if(inTag) {
  72. if(inString) {
  73. super.insertString( off, ""+c, string );
  74. } else {
  75. super.insertString( off, ""+c, tag );
  76. }
  77. } else {
  78. super.insertString( off, ""+c, norm );
  79. }
  80. break;
  81. }
  82. }
  83.  
  84. /*
  85.   * Assuming the '^' char is our cursor,
  86.   * the desired result for input into the document
  87.   * is as follows--
  88.   *
  89.   * [H, i, , T, h,^ r, e]
  90.   * [1, 2, 3, 4, 5, 6, 7]
  91.   *
  92.   * after inserting e past h,
  93.   *
  94.   * [H, i, , T, h, e,^ r, e]
  95.   * [1, 2, 3, 4, 5, 6, 7, 8]
  96.   *
  97.   * -- basically we want the cursor to act like a regular
  98.   * cursor in a text document. That is, we want the cursor
  99.   * to increment by one after we insert a character into the
  100.   * document.
  101.   *
  102.   * http://java.sun.com/javase/6/docs/api/javax/swing/text/Caret.html
  103.   * Shows the Caret API used in the JTextPane. Although a JTextPane
  104.   * will view/modify its Document, ultimately the interface needed to
  105.   * operate on the JTextPane itself is its Caret.
  106.   *
  107.   * I'm assuming that the JTextPane is listening for property and
  108.   * key events, but I'm not entirely sure of the exact relationship
  109.   * between the events occurring on the pane and the Caret's position.
  110.   *
  111.   * This is an expirimental solution. There may be a way to send a
  112.   * hint to the JTextPane (a flag, or maybe another command) such that
  113.   * the Caret can be placed without requiring a reference to an existing
  114.   * JTextPane. This method may not be incredibly practical, but it does
  115.   * form a solution.
  116.   */
  117.  
  118. jp.getCaret().setDot(offs+1);
  119.  
  120. }
  121. }
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 408
Reputation: sciwizeh is on a distinguished road 
Solved Threads: 22
sciwizeh's Avatar
sciwizeh sciwizeh is offline Offline
Posting Pro in Training

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #3
Mar 17th, 2009
thanks for the reply (and welcome to daniweb first post I see) I ended up doing that already, I figured it could be a temporary solution, until someone here might come up with something else, maybe it's the only way, I don't know

thanks for trying Intrade.

Anyone else have a suggestion?
My site, random PM's from people I haven't hear from before will be DELETED
"If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed.",
"If we knew what it was we were doing, it would not be called research, would it? "
-Albert Einstein
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,438
Reputation: Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of 
Solved Threads: 510
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #4
Mar 18th, 2009
Your caret is going to the end of the document because you're removing and re-inserting the entire content. The caret is just staying at the position of the last insert. You can fix that by changing these two lines in your SyntaxDocument2.insertString() method
  1. String str2 = super.getText( 0, super.getLength() );
  2.  
  3. super.remove( 0, super.getLength() );
slightly to get only the "upstream" portion of the document plus the string you are entering
        String str2 = super.getText( 0, offs+str.length() );

        super.remove( 0, str2.length() );
That way you are only operating on the portion up to and including your current insert position and the caret stays at that position.

There is probably an easier way to do that with a DocumentFilter that doesn't require removing and re-inserting all of that content, but I've never used styled documents much so I can't say exactly without playing around with it more. You might take a look at them and see if it could save you all that insert, remove, and re-insert overhead.
Reply With Quote Quick reply to this message  
Join Date: Mar 2009
Posts: 54
Reputation: Intrade is an unknown quantity at this point 
Solved Threads: 5
Intrade Intrade is offline Offline
Junior Poster in Training

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #5
Mar 18th, 2009
Originally Posted by Ezzaral View Post
Your caret is going to the end of the document because you're removing and re-inserting the entire content. The caret is just staying at the position of the last insert. You can fix that by changing these two lines in your SyntaxDocument2.insertString() method
  1. String str2 = super.getText( 0, super.getLength() );
  2.  
  3. super.remove( 0, super.getLength() );
slightly to get only the "upstream" portion of the document plus the string you are entering
        String str2 = super.getText( 0, offs+str.length() );

        super.remove( 0, str2.length() );
That way you are only operating on the portion up to and including your current insert position and the caret stays at that position.

There is probably an easier way to do that with a DocumentFilter that doesn't require removing and re-inserting all of that content, but I've never used styled documents much so I can't say exactly without playing around with it more. You might take a look at them and see if it could save you all that insert, remove, and re-insert overhead.
If I understand the logic correctly--

-Step 2: grab the characters from position 0 to the Caret's current position plus the length of the String that was inserted

-Step 3: remove the characters from the document up to the already inserted String

//... And then of course iterate through each character up to the length of the removed content and insert each character given the appropriate styling per character.

Result: Given that the Caret is positioned at the location of the last insert, the Caret's new position should be at the position just before the 2nd half of the entire String.


If its true that the Caret is positioned at its last insert, couldn't we just insert a 0-lengthed String into the document at a desired position, or is that impossible, or did you provide your solution because it was more efficient?

Thanks

-Intrade
Reply With Quote Quick reply to this message  
Join Date: May 2007
Posts: 4,438
Reputation: Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of Ezzaral has much to be proud of 
Solved Threads: 510
Moderator
Featured Poster
Ezzaral's Avatar
Ezzaral Ezzaral is offline Offline
Industrious Poster

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
1
  #6
Mar 18th, 2009
I just fixed the behavior that he was unhappy with, but yes, it is a bit more efficient. He was re-processing the entire content of the document when he only needed to re-process up to the current insertion point for the highlighting.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 408
Reputation: sciwizeh is on a distinguished road 
Solved Threads: 22
sciwizeh's Avatar
sciwizeh sciwizeh is offline Offline
Posting Pro in Training

Re: Problem extending DefaultStyleDocument--insertString jumps caret to end of document

 
0
  #7
May 22nd, 2009
Thanks for the information, I didn't realize that there were more posts here, because I didn't get the normal e-mail from daniweb. thanks i'll use that Ezzaral.
My site, random PM's from people I haven't hear from before will be DELETED
"If people are good only because they fear punishment, and hope for reward, then we are a sorry lot indeed.",
"If we knew what it was we were doing, it would not be called research, would it? "
-Albert Einstein
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Other Threads in the Java Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC