Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.5.5
    • Fix Version/s: 1.7.2, 1.6.9
    • Component/s: Groovy Console
    • Labels:
      None
    • Environment:
      Windows XP, java 1.5
    • Number of attachments :
      2

      Description

      Loading of certain groovy files results in a scrambled version of the file, i.e. there's additional code added to the end of the file.
      I included a file that shows the error in my app.

      I hope this isn't a duplicate. I couldn't find a matching bug report.

      1. Console.patch
        0.6 kB
        Tim Yates
      2. detailsView.groovy
        14 kB
        Joern Huxhorn

        Activity

        Hide
        Joern Huxhorn added a comment -

        Any news on this problem?

        I think it's quite sad that this otherwise great feature of groovy is currently crippled.

        Show
        Joern Huxhorn added a comment - Any news on this problem? I think it's quite sad that this otherwise great feature of groovy is currently crippled.
        Hide
        Danno Ferrin added a comment - - edited

        No progress. It's a combination of not understanding why it's breaking (since this was donated code) combined with a lack of free time to devote to it. The solution may be to punt and switch to JSyntaxPane.

        Show
        Danno Ferrin added a comment - - edited No progress. It's a combination of not understanding why it's breaking (since this was donated code) combined with a lack of free time to devote to it. The solution may be to punt and switch to JSyntaxPane .
        Hide
        Tim Yates added a comment -

        It's a problem with the DocumentFilter of some sort...

        If inside groovy.ui.Console, you change loadScriptFile to:

            void loadScriptFile(File file) {
                swing.edt {
                    inputArea.editable = false
                }
                swing.doOutside {
                    try {
                        consoleText = file.readLines().join('\n')
                        scriptFile = file
                        swing.edt {
                            updateTitle()
        
                            // Turn off DocumentFilter
                            def doc = inputArea.document
                            def filter = doc.documentFilter
                            doc.documentFilter = null
                            // END
        
                            inputArea.setText( consoleText )
        
                            // Then turn it back on again
                            doc.documentFilter = filter
                            // END
        
                            setDirty(false)
                            inputArea.caretPosition = 0
                        }
                    } finally {
                        swing.edt { inputArea.editable = true }
                    }
                }
            }
        

        It loads the document properly, but doesn't style it again until you type in some more text (and this is just trying to cure the symptoms, rather treating the underlying illness)

        I'll have a look into StructuredSyntaxDocumentFilter and see if I can see anything...but it all gets a bit frantic

        Show
        Tim Yates added a comment - It's a problem with the DocumentFilter of some sort... If inside groovy.ui.Console, you change loadScriptFile to: void loadScriptFile(File file) { swing.edt { inputArea.editable = false } swing.doOutside { try { consoleText = file.readLines().join('\n') scriptFile = file swing.edt { updateTitle() // Turn off DocumentFilter def doc = inputArea.document def filter = doc.documentFilter doc.documentFilter = null // END inputArea.setText( consoleText ) // Then turn it back on again doc.documentFilter = filter // END setDirty( false ) inputArea.caretPosition = 0 } } finally { swing.edt { inputArea.editable = true } } } } It loads the document properly, but doesn't style it again until you type in some more text (and this is just trying to cure the symptoms, rather treating the underlying illness) I'll have a look into StructuredSyntaxDocumentFilter and see if I can see anything...but it all gets a bit frantic
        Hide
        Tim Yates added a comment -

        I think I found it...

        When groovy.ui.Console:loadScriptFile called

        inputArea.text = consoleText

        the text was being passed to the groovy.ui.text.StructuredSyntaxDocumentFilter in 4096 char "chunks" rather than all at once

        This meant that the code around the boundaries was garbled, and so the RegExp wonder that is LexerNode was having a bit of choking fit whilst trying to style up the document (hence chunks of code were getting left behind, and put out of order)

        The stuff at the bottom of the file (I think) was the tails of the chunks that it couldn't handle

        I have submitted a patch to this issue which passes the text straight to the Document rather than via the JTextArea.text method, and this seems to get round the problem

        Again, hope it's ok

        Tim

        Show
        Tim Yates added a comment - I think I found it... When groovy.ui.Console:loadScriptFile called inputArea.text = consoleText the text was being passed to the groovy.ui.text.StructuredSyntaxDocumentFilter in 4096 char "chunks" rather than all at once This meant that the code around the boundaries was garbled, and so the RegExp wonder that is LexerNode was having a bit of choking fit whilst trying to style up the document (hence chunks of code were getting left behind, and put out of order) The stuff at the bottom of the file (I think) was the tails of the chunks that it couldn't handle I have submitted a patch to this issue which passes the text straight to the Document rather than via the JTextArea.text method, and this seems to get round the problem Again, hope it's ok Tim
        Hide
        Guillaume Laforge added a comment -

        Thank you! Sorry it took so long to fix it

        Show
        Guillaume Laforge added a comment - Thank you! Sorry it took so long to fix it
        Hide
        Joern Huxhorn added a comment -

        Yay! anyway

        Show
        Joern Huxhorn added a comment - Yay! anyway
        Hide
        Joern Huxhorn added a comment -

        I just checked this and it's still broken in 1.7-rc-2.

        I use:
        console.setScriptFile(messageViewGroovyFile);
        JTextPane inputArea = console.getInputArea();
        inputArea.setText(text);

        I read text manually already.

        Am I using Console wrongly?

        Show
        Joern Huxhorn added a comment - I just checked this and it's still broken in 1.7-rc-2. I use: console.setScriptFile(messageViewGroovyFile); JTextPane inputArea = console.getInputArea(); inputArea.setText(text); I read text manually already. Am I using Console wrongly?
        Hide
        Paul King added a comment -

        adjusting fix versions given that it was reopened

        Show
        Paul King added a comment - adjusting fix versions given that it was reopened
        Hide
        Tim Yates added a comment -

        Is this bug now with embedding the console in your own application?

        Not just using the command line to fire up the console?

        Show
        Tim Yates added a comment - Is this bug now with embedding the console in your own application? Not just using the command line to fire up the console?
        Hide
        Joern Huxhorn added a comment -

        It's embedded in an application.

        You can take a look at the actual code at
        http://github.com/huxi/lilith/blob/master/lilith/src/main/java/de/huxhorn/lilith/swing/preferences/PreferencesDialog.java

        The relevant part is contained in the method editDetailsFormatter().

        Show
        Joern Huxhorn added a comment - It's embedded in an application. You can take a look at the actual code at http://github.com/huxi/lilith/blob/master/lilith/src/main/java/de/huxhorn/lilith/swing/preferences/PreferencesDialog.java The relevant part is contained in the method editDetailsFormatter().
        Hide
        Tim Yates added a comment -

        What happens if instead of:

        inputArea.setText(text);
        console.setDirty(false);
        

        You do

        inputArea.getDocument().remove( 0, inputArea.document.length )
        inputArea.getDocument().insertString( 0, text, null )
        

        The same as I do in the patch I supplied here:
        http://jira.codehaus.org/browse/GROOVY-2790?focusedCommentId=187785&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_187785

        (see Console.patch at the top of this issue)

        Does that fix it?

        Show
        Tim Yates added a comment - What happens if instead of: inputArea.setText(text); console.setDirty( false ); You do inputArea.getDocument().remove( 0, inputArea.document.length ) inputArea.getDocument().insertString( 0, text, null ) The same as I do in the patch I supplied here: http://jira.codehaus.org/browse/GROOVY-2790?focusedCommentId=187785&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_187785 (see Console.patch at the top of this issue) Does that fix it?
        Hide
        Joern Huxhorn added a comment - - edited

        Yes, the following code works:

        JTextPane inputArea = console.getInputArea();
        //inputArea.setText(text);
        Document doc = inputArea.getDocument();
        try
        {
        	doc.remove( 0, doc.getLength() );
        	doc.insertString( 0, text, null );
        }
        catch(BadLocationException e)
        {
        	if(logger.isWarnEnabled()) logger.warn("Exception while setting source!", e);
        }
        console.setDirty(false);
        inputArea.setCaretPosition(0);
        inputArea.requestFocusInWindow();
        

        Thanks for the tip!

        The question is: is this bug fixed?
        There should probably be at least some method that does the above. I also don't really understand what's happening here, i.e. exactly why setText is failing like this.

        Show
        Joern Huxhorn added a comment - - edited Yes, the following code works: JTextPane inputArea = console.getInputArea(); //inputArea.setText(text); Document doc = inputArea.getDocument(); try { doc.remove( 0, doc.getLength() ); doc.insertString( 0, text, null ); } catch(BadLocationException e) { if(logger.isWarnEnabled()) logger.warn("Exception while setting source!", e); } console.setDirty(false); inputArea.setCaretPosition(0); inputArea.requestFocusInWindow(); Thanks for the tip! The question is: is this bug fixed? There should probably be at least some method that does the above. I also don't really understand what's happening here, i.e. exactly why setText is failing like this.
        Hide
        Tim Yates added a comment -

        The syntax highlighter is kicked off by Document events

        When you call setText, Swing seems to buffer the text you're adding, and it goes into the Document in chunks

        The problem is that the syntax highlighter (which is a huge Rube Goldberg regexp parser of genius) startes parsing the text before all of the chunks have been added

        If one of these chunks splits in the middle of a loop or a string, then the highlighter chokes and you end up with the remaining code left in the highlighter's buffer

        All of this remainging code is then spat out into the end of the document

        So by skipping setText, and going straight for the document.insertString method, we make sure that the all the Groovy code is there at the same time when the event to highlight it fires

        This is the cleanest solution I could find when I looked through the code back in the summer

        Show
        Tim Yates added a comment - The syntax highlighter is kicked off by Document events When you call setText, Swing seems to buffer the text you're adding, and it goes into the Document in chunks The problem is that the syntax highlighter (which is a huge Rube Goldberg regexp parser of genius) startes parsing the text before all of the chunks have been added If one of these chunks splits in the middle of a loop or a string, then the highlighter chokes and you end up with the remaining code left in the highlighter's buffer All of this remainging code is then spat out into the end of the document So by skipping setText, and going straight for the document.insertString method, we make sure that the all the Groovy code is there at the same time when the event to highlight it fires This is the cleanest solution I could find when I looked through the code back in the summer

          People

          • Assignee:
            Guillaume Laforge
            Reporter:
            Joern Huxhorn
          • Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: