Results 1 to 16 of 16
  1. #1
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default how to temporarily suspend while loop?

    how to temporarily suspend while loop until a button pressed?

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    There's a bad code smell to this question, suggesting that you're breaking some rules of event-driven gui programming. Can you elaborate on just what you're trying to do?

  3. #3
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default

    I'm writing spell checker program, which checks every word of some .txt file. it reads file while end of file is reached, and when it finds incorrect word it suggests correct variants in JList. and user chooses one and presses "next" button. Then it continues reading and searching for incorrect word.

    while(all words in a file is not read)
    {
    check(word);//this returns array of suggestions
    if("next" button is pressed)
    {list.getSelectedWord() and continue while loop}
    else {suspend loop until "next" button is pressed}

    }

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

  5. #5
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default

    no, I don't want to use modal dialog. and yes, it is swing app.

  6. #6
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I assume you are doing something like writing a new version of the file with corrections made in it.

    Try writing a checkFile() method which reads words and writes them to the output file. It does this until it hits a bad word at which point it returns a list of suggestions (or null if the end of file is reached). The point is that this method is over and done with once it hits the next bad word.

    This method could be called in response to a "next" button click followed by using the returned values to populate some gui element displaying the suggestions.

    Quite a different event handler would handle selection of an item. (eg by writing it to the output file and making the "next" button active again)

    ---------------------

    Aside - some languages do implement iterators using a function that is effectively "paused" after it returns the next value.

  7. #7
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default

    pbrockway2, thanks. u hit the nail on the head. I'm doing the program you described. yes, I have checkFile() method and it returns list of suggestions. but that's where the problem occurs. I want to suspend the method until "next" is hit and continue working with this method, with while (or any other)loop in this method to be more precise. I don't see what do you mean "this method is over and done with once it hits the next bad word". do you mean that every time the button is hit, checkFile() starts reading file from the beginning???Isn't it expensive?

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    I don't see what do you mean "this method is over and done with once it hits the next bad word"

    I meant that we have to accept up front that Java does not support "freezing" methods. Once the method returns, it returns and that's it.

    do you mean that every time the button is hit, checkFile() starts reading file from the beginning?
    Not at all. I imagine that somewhere in the model that represents the data there is a Reader instance. (some subclass of Reader).

    The checkFile() method will have a loop which uses this reader to
    * get the next word
    * check it
    * if good write it to the output file
    * otherwise ceate and return the suggestion list

    It does this over and over until it hits a bad word or end of file. The thing is that next time checkFile() is called that Reader instance will be in exactly the right place for the checking to pick up where it left off! There is no need for it start again from the beginning (and that wouldn't help because it wouldn't know where to start from...)

  9. #9
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default

    sorry, I didn't understand you. can you clarify use of Reader instance, how it will know where it left off?Here is piece of what I've done so far. I would appreciate if you associate your answer with this code
    // this method supposed to return array, but as i have problem i left it void temporarily
    public void reader() throws IOException
    {
    checker= new Checker();

    String line;
    String write;

    while ((line = reader.readLine()) != null) {
    StringTokenizer st = new StringTokenizer(line);
    while(st.hasMoreTokens())
    {
    currentArray = checker.receiveList(st.nextToken());
    // here is problem. how I return currentArray to populate with it GUI component and how to suspend it until user hits button
    }

    // this is in Checker class
    public String[] receiveList(String string)
    { find(string); // long coding which returns arrayList of suggestions;
    String array[] = list.toArray();
    return array;
    }

  10. #10
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    It's confusing to call the method reader() and also have a BufferedReader(?) called reader.

    You cannot suspend the reader() method. Therefore it isn't a problem: it just can't be done. Rather, what remembers the state (where to read from) is the readervariable.

    The procedure I outlined above would look in code something like the following:

    Java Code:
    import java.io.IOException;
    import java.io.Reader;
    import java.io.Writer;
    
    public class FileChecker {
        private Reader in;
        private Writer out;
    
        public FileChecker(Reader in, Writer out) {
            this.in = in;
            this.out = out;
        }
    
            /**
             * Copies words from in to out until it finds a misspelling.
             * @return an array of suggestions for the misspelt word or null if EOF encountered
             */ 
        public String[] doCheck() throws IOException {
                // this is suitable for being called repeatedly in response to 
                // a "next" button click
            while(true) {
                String word = getWord();
                if(word == null) {
                    return null;
                }
                String[] suggestions = getSuggestions(word); 
                if(suggestions == null) {
                    writeWord(word);
                } else {
                    return suggestions;
                }
            }
        }
        
            /**
             * Returns the next [i]word[/i] from the stream or null if there are no more characters.  
             * A word consists either entirely of non whitespace characters or entirely of 
             * whitespace characters.
            */
        private String getWord() {
            // insert magic along these lines...
            // read in character by character accumulating the results which
            // are returned once the end of the word is encountered.
        	
            // The reader in is used to get the characters.  It will pick up each 
            // time from where it left off the last time this method was called.
    
            // You have a bit of a problem implementing this method because
            // you can't recognise the end of a word until you have read the
            // first letter of the next word.  Perhaps make in a PushbackReader?
            // Or, better I think, have an instance variable set to the character
            // which has been read but not yet returned to be written.  (Such
            // instance variables seem to be the way iterators are implemented.)
    
            return null;
        }
        
            /**
             * Returns an array of suggestions for incorrectly spelled words, or null if the
             * word is OK or consists entirely of whitespace.
             */
        private String[] getSuggestions(String word) {
            // insert your magic here
            return null;
        }
        
            /**
             * Writes a word.
             */
        public void writeWord(String word) throws IOException {
                // this is suitable for being called in response to a suggestion
                // being chosen in the gui
            out.write(word);
        }
    }

    Notice that the user of this class (the GUI?) will have to arrange things so that doCheck() is not called twice without an intervening writeWord(). Commonly this is done by having the click handler for the "next" button disable the button and the handler for the suggestion list handler reenable the button.

    The GUI will have to also deal appropriately with the exceptions - the slings and arrows of outrageous I/O: hopefully with something better than a bare bodkin. And it will have to do the right thing once the EOF is detected.
    Last edited by pbrockway2; 02-20-2011 at 03:25 AM.

  11. #11
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,585
    Rep Power
    12

    Default

    can you clarify use of Reader instance, how it will know where it left off?

    This is the key to seeing your way through the problem. I have no clue how a Reader instance does it, but you call reader.read(), reader.read(), reader.read() and it returns the characters in exactly the order they appear in the source.

    Likewise if it goes reader.read() ... wait 5 minutes while the user chooses a correction ... reader.read() ... wait 5 more minutes ... reader.read(). The three characters returned will be in exactly the right order. It is the Reader instance's job to remember where it was last time. (Likewise for BufferedReader's readLine(), Scanner's nextLine() etc: It would be a bit silly if they didn't remember and returned the lines in any old order.)

  12. #12
    toadaly is offline Senior Member
    Join Date
    Jan 2009
    Posts
    671
    Rep Power
    6

    Default

    Quote Originally Posted by Nazerke View Post

    while(all words in a file is not read)
    {
    check(word);//this returns array of suggestions
    if("next" button is pressed)
    {list.getSelectedWord() and continue while loop}
    else {suspend loop until "next" button is pressed}

    }

    To suspend, I would probably call 'wait', and then the 'Next' button would issue a notify() to wake the loop up.

  13. #13
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,783
    Blog Entries
    7
    Rep Power
    21

    Default

    Quote Originally Posted by toadaly View Post
    To suspend, I would probably call 'wait', and then the 'Next' button would issue a notify() to wake the loop up.
    I'd use a SynchronousQueue<Command> where the Command is an interface that specifies what needs to be done. The while loop body tries to fetch the element from the queue and the buttons put a Command in the queue. If no element is available the while loop body waits (the queue takes care of that) and in no element is needed the buttons are disabled.

    Using the classes in the java.util.concurrent package greatly simplify your code and the take away those wait(), notify() and syncing stuff from your code.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  14. #14
    Nazerke is offline Member
    Join Date
    Feb 2011
    Location
    London
    Posts
    7
    Rep Power
    0

    Default

    thank you for your time. seems like i really can't understand Readers concept of continuing from where it was last time, rather than starting everything again.

    this is just some silly example, which reads only two lines of text

    static String line;
    public static void reader() throws FileNotFoundException, IOException{
    BufferedReader reader = new BufferedReader(new FileReader("text.odt"));
    int i=0;
    while ((line = reader.readLine()) != null) {
    if(i<3)
    System.out.println(line);
    i++;
    }}
    when you call it from another class like a.reader() it will return 1st and 2nd line of code, and if you call it again like b.reader() it will also return 1st and 2nd line, but not 3rd and 4th lines, as I understand you. therefore, it doesn't remember where it left off.

    and why would you use character reader, but not line reader and then tokenize it in getWord() method?anyways that is not real problem

  15. #15
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,783
    Blog Entries
    7
    Rep Power
    21

    Default

    If you open a new FileReader on a file again and again those FileReaders will read the same file again and again. One FileReader doesn't know that another one has already read some bytes/characters from that one file.

    kind regards,

    Jos
    cenosillicaphobia: the fear for an empty beer glass

  16. #16
    kennyman94 is offline Member
    Join Date
    Feb 2011
    Posts
    24
    Rep Power
    0

    Default

    why not just have the check() method wait for the response and then return from the method (and back into the loop) after the problem has been solved?

    for example:

    Java Code:
    public void read(){
        String temp = "";
        while(temp != null){
            temp = getNextWord();
            check(temp);
        }
    }
    
    public void check(String temp){
        if(temp is spelled correctly){
            return;
        }else{
            while(!resolved){
                try{
                    Thread.currentThread().sleep(5);
                }
            }
            makeChanges();
            return;
        }
    }
    just be sure to to keep everything concurrent. right?

    although using a que does seem like a great idea.
    Last edited by kennyman94; 02-24-2011 at 06:17 AM.

Similar Threads

  1. Temporarily add CA certificate
    By ohm in forum Advanced Java
    Replies: 0
    Last Post: 02-15-2011, 01:07 PM
  2. Hibernate/Suspend/PowerManagement
    By narthir in forum New To Java
    Replies: 0
    Last Post: 02-09-2011, 10:50 PM
  3. Can we use suspend() in jdk1.6 ?
    By makpandian in forum Threads and Synchronization
    Replies: 1
    Last Post: 10-26-2010, 03:23 PM
  4. suspend a method
    By mtz1406 in forum Threads and Synchronization
    Replies: 6
    Last Post: 10-21-2009, 09:36 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •