Using wait() but making the gui responsive

Discussion in 'Java' started by James Nugent, May 4, 2004.

  1. James Nugent

    James Nugent Guest

    Hi there,

    I am writing an interesting little app that uses speech recognition.
    I have a number of sentences (cycled through using a for loop) that
    each have a number of words. What I want to happen is for the words
    to appear on screen and then disappear after the user has said them
    all or after a time out.

    I tried using wait() to pause the program, and a notifyAll to wake it
    up when the user has said all the words. However, this causes the gui
    to hang.

    I don't know if this is the best idea so would appreciate all offers
    of help.

    Thanks,
    James

    Code:


    import java.util.Vector;
    import javax.swing.JLabel;
    import javax.swing.JLayeredPane;
    import javax.speech.recognition.*;
    import javax.speech.*;
    import java.util.Locale;
    import javax.swing.JOptionPane;
    import java.awt.FlowLayout;
    import javax.swing.SwingUtilities;

    public class Sentence extends ResultAdapter{

    Recognizer rec;
    RuleGrammar gram;
    Vector words = new Vector();
    StoryWord currentWord;
    String picture;
    boolean errorFound;
    Helper helper;
    JLabel pictureHolder;
    Student currentStudent;
    Vector spokenWords;
    JLayeredPane pane;
    boolean finished=false;
    int wordPointer=0;
    int helpCounter;
    Thread t;

    public Sentence(JLabel pictureHolder, Helper helper, Student
    student, String picture) {
    this.pictureHolder=pictureHolder;
    this.helper=helper;
    this.currentStudent=student;
    this.picture=picture;

    this.errorFound=false;
    try{


    }
    catch(Exception e){
    JOptionPane.showMessageDialog(null,"Error allocating recogniser
    "+e.toString(),"Sentence Error",
    JOptionPane.ERROR_MESSAGE);
    }


    }

    public void setRecognizer(Recognizer r){
    this.rec=r;
    rec.addResultListener(this);
    if (rec.getRuleGrammar("Sentence")==null)
    gram = rec.newRuleGrammar("Sentence");
    else gram = rec.getRuleGrammar("Sentence");
    gram.setEnabled(true);
    String[] rules = gram.listRuleNames();
    for (int i=0; i<rules.length;i++){
    gram.deleteRule(rules); //delete the existing rules
    }
    rec.addResultListener(this);
    }

    public void addWord(StoryWord theWord){
    try{
    words.add(theWord);
    System.out.print(theWord.getText()+" ");
    }
    catch (Exception e){
    JOptionPane.showMessageDialog(null,"Error adding word:
    "+e.toString(),"Sentence Error",
    JOptionPane.ERROR_MESSAGE);
    }

    }

    public void resultAccepted(ResultEvent e) {//spoken word matches a
    word in grammar
    String spokenWord="";

    Result r = (Result) (e.getSource());
    ResultToken tokens[] = r.getBestTokens();

    for (int i = 0; i < tokens.length; i++)
    spokenWord =tokens.getSpokenText();

    processWord(spokenWord);
    }

    public void resultRejected(ResultEvent e){
    String spokenWord=""; //word spoken doesn't match that of grammar
    processWord(spokenWord);
    }

    public synchronized void processWord(String word){//process the
    incoming word
    System.out.println(word);
    StoryWord currentWord = new StoryWord("nullxxyy");
    if (wordPointer<words.size()){
    currentWord = (StoryWord) words.elementAt(wordPointer);
    }
    StoryWord previousWord = new StoryWord("nullxxyy");
    if (wordPointer!=0){
    previousWord = (StoryWord) words.elementAt(wordPointer - 1);
    }

    StoryWord nextWord = new StoryWord("nullxxyy");
    if(wordPointer+1<words.size()){
    nextWord = (StoryWord)words.elementAt(wordPointer+1);
    }

    if (word.equals(currentWord.getText())){//word is what we expect
    if (wordPointer==words.size()) notifyAll(); //we have reached
    the end
    else wordPointer++;
    }
    else if(word.equals(previousWord.getText()))//deals with
    repetition of single word or self correction
    //wordpointer remains the same
    previousWord.setMisspoken(false); //correction a success

    else if(word.equals("")) //mispronunication
    currentWord.setMisspoken(true); //this word is incorrect

    else{ //we must search forwards (for multiple skips), check for
    possible restarts, or backsteps
    boolean found = false;
    int i = wordPointer;
    while(i<words.size()&&found==false){
    StoryWord search = (StoryWord)words.elementAt(i); //find the
    word
    if(search.getText().equals(word)) found = true;
    else i++;
    }
    if(found==true){ //we have skipped a long way forward
    for (int j=wordPointer;j<i;i++){
    StoryWord incorrect = (StoryWord)words.elementAt(j); //set
    in between words incorrect
    incorrect.setSkipped(true);
    wordPointer=i+1; //set the pointer to the next word
    }
    }
    else{//we didn't find the word, start search backwards
    found = false;
    i=wordPointer;
    while(i>=0&&found==false){
    StoryWord search = (StoryWord)words.elementAt(i); //find the
    word
    if(search.getText().equals(word)) found = true;
    else i--;
    }
    wordPointer=i+1; //reset the word pointer
    }
    }
    }

    public synchronized double show(JLayeredPane panel){
    this.pane=panel;
    double score=0;
    panel.removeAll();
    panel.setLayout(new FlowLayout(FlowLayout.LEADING));
    System.out.println("Showing sentence");
    for (int i=0;i<words.size();i++){
    StoryWord word = (StoryWord)words.elementAt(i);

    //add the word to the pane in the right place
    panel.add(word);
    word.setVisible(true);
    System.out.print(word.getText()+" ");
    }



    panel.repaint();
    panel.updateUI();
    panel.validate();

    this.errorFound=true;
    int tries=0;
    int errors=0;

    String[] wordRules = new String[words.size()];
    for (int i=0;i<words.size();i++){
    StoryWord sw = (StoryWord)words.elementAt(i);
    wordRules=sw.getText();
    }
    Rule r = new RuleAlternatives(wordRules);
    gram.setRule("Sentence",r,true);
    try{
    rec.commitChanges();
    }
    catch(Exception e){
    e.printStackTrace();
    }

    while(tries<3&&this.errorFound==true){
    wordPointer=0;
    this.finished=false;
    tries++;
    this.errorFound=false;

    try{
    rec.resume();
    rec.requestFocus();
    rec.waitEngineState(Recognizer.LISTENING);
    }
    catch(Exception e){
    JOptionPane.showMessageDialog(null,"Error resuming
    recogniser: "+e.toString(),"Sentence Error",
    JOptionPane.ERROR_MESSAGE);
    }
    //while(!finished);//wait here until finished

    try{
    wait(words.size() * 10000);
    }
    catch (Exception e){
    e.printStackTrace();
    }
    rec.suspend();//suspend recognizer
    for(int i=0;i<words.size();i++){
    StoryWord temp = (StoryWord)words.elementAt(i);
    if (temp.isIncorrect()){
    this.errorFound = true; //find out if errors have been
    made
    errors++;
    }
    }
    //if errors then run correction routine
    if (tries==1) score = (words.size()-errors)/words.size();
    //calculate score first time round
    if (this.errorFound){
    correctionRoutine();
    helpCounter++;
    }
    }
    //if tries != 1 then update learning preferences
    if(tries!=1&&!errorFound){ //i.e. help has been made and has
    corrected mistakes
    currentStudent.incrementPreference(this.helpCounter % 4);
    }
    if(tries==3&&errorFound){ //we have had three goes and there is
    still errors
    for(int i=0;i<words.size();i++){
    StoryWord sw = (StoryWord)words.elementAt(i);
    if(sw.isIncorrect()) helper.say("This word is said
    "+sw.getText());
    }
    helper.say("Here is the whole sentence");
    for (int i=0;i<words.size();i++){
    StoryWord sw = (StoryWord)words.elementAt(i);
    sw.sayWord();
    }
    }
    return score;
    }

    public void correctionRoutine(){
    LearningPreference pref =
    currentStudent.getLearningPreference(helpCounter);
    for (int i=0;i<words.size();i++){
    StoryWord sw = (StoryWord)words.elementAt(i);
    if (sw.isIncorrect()){ //this word is incorrect
    if(sw.wasMisspoken()) helper.say("I don't think you said this
    word correctly");
    else if (sw.wasSkipped()) helper.say("I think you missed this
    word out");
    sw.setHighlighted(true);
    switch(pref.getType()){
    case LearningPreference.PHONIC: sw.givePhonicHint(); break;
    case LearningPreference.PICTURE: sw.givePictureHint();
    break;
    case LearningPreference.RHYME: sw.giveRhymeHint(); break;
    case LearningPreference.SYNTAX: sw.giveSyntaxHint(); break;
    }
    sw.setHighlighted(false);
    }
    }
    helper.say("Read the sentence again for me");
    }

    public void setErrorFound(boolean error){
    this.errorFound=error;
    }

    }
    James Nugent, May 4, 2004
    #1
    1. Advertising

  2. "James Nugent" <> wrote in message
    news:...
    > Hi there,
    >
    > I am writing an interesting little app that uses speech recognition.
    > I have a number of sentences (cycled through using a for loop) that
    > each have a number of words. What I want to happen is for the words
    > to appear on screen and then disappear after the user has said them
    > all or after a time out.
    >
    > I tried using wait() to pause the program, and a notifyAll to wake it
    > up when the user has said all the words. However, this causes the gui
    > to hang.
    >
    > I don't know if this is the best idea so would appreciate all offers
    > of help.


    I take it that your code called directly from the GUI thread--the one from
    which you receive UI requests. If you wait or block this thread your GUI
    will halt. In fact, your GUI won't even be able to update the screen until
    it finishes with your code. You'll need to find some way of putting the
    speech recognition into a separate thread so that the GUI will update and
    continue to accept requests while the recognition work is going on. A
    closer examination of your code may show how to structure it for background
    use.

    Cheers,
    Matt Humphrey http://www.iviz.com/
    Matt Humphrey, May 4, 2004
    #2
    1. Advertising

  3. James Nugent wrote:
    > I tried using wait() to pause the program, and a notifyAll to wake it
    > up when the user has said all the words. However, this causes the gui
    > to hang.


    Get the FAQ for comp.lang.java.gui. This is in the top 5 of questions.
    Also you really want to work through Sun's GUI tutorial. A pointer is in
    the FAQ, too.

    /Thomas
    Thomas Weidenfeller, May 4, 2004
    #3
  4. James Nugent

    Roedy Green Guest

    On 4 May 2004 07:34:15 -0700, (James Nugent) wrote
    or quoted :

    >I tried using wait() to pause the program, and a notifyAll to wake it
    >up when the user has said all the words. However, this causes the gui
    >to hang.
    >
    >I don't know if this is the best idea so would appreciate all offers
    >of help.


    never put the GUI Swing thread to sleep. Use a timer or another
    thread.

    See http://mindprod.com/jgloss/sleep.html
    http://mindprod.com/jgloss/timer.html

    --
    Canadian Mind Products, Roedy Green.
    Coaching, problem solving, economical contract programming.
    See http://mindprod.com/jgloss/jgloss.html for The Java Glossary.
    Roedy Green, May 4, 2004
    #4
  5. James Nugent

    Guest

    (James Nugent) wrote in message news:<>...
    > Hi there,
    >
    > I am writing an interesting little app that uses speech recognition.
    > I have a number of sentences (cycled through using a for loop) that
    > each have a number of words. What I want to happen is for the words
    > to appear on screen and then disappear after the user has said them
    > all or after a time out.
    >
    > I tried using wait() to pause the program, and a notifyAll to wake it
    > up when the user has said all the words. However, this causes the gui
    > to hang.
    >
    > I don't know if this is the best idea so would appreciate all offers
    > of help.
    >
    > Thanks,
    > James
    >
    >


    Take a look at SwingUtilities.invokeAndWait or SwingUtilities.invokeLater.
    , May 4, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Frank
    Replies:
    0
    Views:
    323
    Frank
    Nov 21, 2003
  2. =?Utf-8?B?SmF3YWhhcg==?=

    ASPX page un responsive. after opening Modal Dialog

    =?Utf-8?B?SmF3YWhhcg==?=, Sep 29, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    486
    Lau Lei Cheong
    Sep 30, 2004
  3. Timasmith
    Replies:
    12
    Views:
    590
    Julian Treadwell
    Dec 8, 2006
  4. Replies:
    0
    Views:
    317
  5. JohnnyFive

    Sleep timer but still responsive?

    JohnnyFive, Jan 28, 2010, in forum: Python
    Replies:
    7
    Views:
    408
    Dave Angel
    Jan 30, 2010
Loading...

Share This Page