943,752 Members | Top Members by Rank

Ad:
  • Java Discussion Thread
  • Marked Solved
  • Views: 1045
  • Java RSS
Mar 16th, 2009
0

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

Expand Post »
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:
java Syntax (Toggle Plain Text)
  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. }
java Syntax (Toggle Plain Text)
  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. }
Reputation Points: 73
Solved Threads: 22
Posting Pro in Training
sciwizeh is offline Offline
423 posts
since Jun 2008
Mar 17th, 2009
0

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

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.

Java Syntax (Toggle Plain Text)
  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. }

Java Syntax (Toggle Plain Text)
  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. }
Reputation Points: 43
Solved Threads: 13
Junior Poster
Intrade is offline Offline
122 posts
since Mar 2009
Mar 17th, 2009
0

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

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?
Reputation Points: 73
Solved Threads: 22
Posting Pro in Training
sciwizeh is offline Offline
423 posts
since Jun 2008
Mar 18th, 2009
0

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

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
Java Syntax (Toggle Plain Text)
  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.
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 838
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
Mar 18th, 2009
0

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

Click to Expand / Collapse  Quote originally posted by Ezzaral ...
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
Java Syntax (Toggle Plain Text)
  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
Reputation Points: 43
Solved Threads: 13
Junior Poster
Intrade is offline Offline
122 posts
since Mar 2009
Mar 18th, 2009
1

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

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.
Moderator
Featured Poster
Reputation Points: 3239
Solved Threads: 838
Posting Genius
Ezzaral is offline Offline
6,761 posts
since May 2007
May 22nd, 2009
0

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

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.
Reputation Points: 73
Solved Threads: 22
Posting Pro in Training
sciwizeh is offline Offline
423 posts
since Jun 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Java Forum Timeline: Can someone check to this method...
Next Thread in Java Forum Timeline: Socket Programming Ports





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC