13 Replies Latest reply: Oct 6, 2010 3:58 PM by 802645 RSS

    Method of class gets called first, then constructor ???

    802645
      Hi everyone.

      I have a question regarding the execution order.
      I am developing a mobile application against CLDC and MIDP in netbeans.

      Somewhere I have an if clause I want to evaluate:
      if (new Message("Delete record?", false, recordsList).getResponse()) {
           ...
      }
      The message class is a wrapper that runs another class instance in a new thread.
      public class Message {
      
          private boolean response;
          private Displayable displayable;
      
          public Message(final String message, final boolean yesAsDefault, final Displayable displayable){
              this.displayable = displayable;
              new Thread(new Runnable() {
      
                  public void run() {
                      Msg msg = new Msg(message, yesAsDefault);
                      ThreadEvent.await();
                      response = msg.getResponse();
      
                  }
              }).start();
          }
          public boolean getResponse() {
              DisplayManager.setCurrent(displayable);
              return response;
          }
      }
      The problem I have is at the if clause. There, the getResponse gets returned first (being always false as it is not set), and the executes the constructor (from where the response is to be set from msg.getResponse.

      I found out about this stepping into the code.

      The issue I am trying to resolve is when an command is selected (eg deleteRecord) to have a confirmation dialog (Alert) with yes / no responses, and wait on the response to continue further.
      Thread synchronizing is achieved in ThreadEvent.await(); where it locks on an Object (works perfectly in other uses).

      So the problem really is, why is the method return first and then the constructor executed?

      What I want to do is initialize, display and wait for the alert response in one line that returns a boolean to be used directly in the if clause.

      And pointers???

      Apologies to Darryl. I knew it had to have a code tag somewhere! My bad.
        • 1. Re: Method of class gets called first, then constructor ???
          DarrylBurke
          Moderator advice: Please read the announcements at the top of the forum listing. They are there for a purpose.

          db
          • 2. Re: Method of class gets called first, then constructor ???
            DarrylBurke
            To get better help sooner, post a SSCCE (Short, Self Contained, Compilable and Executable) example that demonstrates the incorrect behaviour.

            db
            • 3. Re: Method of class gets called first, then constructor ???
              802645
              I am sorry for not using the code tags. I got redirected here from sun forums and missed the existing posts! However I cannot edit the post now.
              • 4. Re: Method of class gets called first, then constructor ???
                DarrylBurke
                However I cannot edit the post now.
                Are you sure?

                db
                • 5. Re: Method of class gets called first, then constructor ???
                  796440
                  Dimitrios wrote:
                  The problem I have is at the if clause. There, the getResponse gets returned first (being always false as it is not set), and the executes the constructor
                  You mean the getResponse on the same line with the if and the constructor? No, absolutely 100% guaranteed that is not being called before the constructor.

                  However, your constructor starts a thread which calls a getResponse message.

                  Have a Message class and a Msg class is a wonky and confusing design. Especially since both have getResponse(), and especially since one creates that other in its own constructor. I think you need some serious re-design.
                  • 6. Re: Method of class gets called first, then constructor ???
                    802645
                    hi jverd,

                    I know this is more than confusing code. It's bad code with unnecessary complexity, however it is the only way I found to have a class wait for input from another (In this case the if clause evaluation should halt until the response boolean (from Msg actually, passed to Message in the example) is returned.

                    I know that the constructor is ALWAYS executed first upon instantiation, however when stepping through the code it seems that the method is returned first (thus the return boolean is always false).

                    The only way I found to be able to do this is to instantiate to a new thread and lock on a synchronized object until the selected file is set and the object lock is released.

                    The code that calls Message is:
                        public boolean deleteRecord() {
                                if (new Message("Delete record?", false, recordsList).getResponse()) {
                                            ... code to delete record
                                }
                            return false;
                        }
                    The "lame" Message class:
                    import javax.microedition.lcdui.Displayable;
                    
                    public class Message {
                    
                        private boolean response;
                        private Displayable displayable;
                    
                        public Message(final String message, final boolean yesAsDefault, final Displayable displayable){
                            this.displayable = displayable;
                            new Thread(new Runnable() {
                    
                                public void run() {
                                    Msg msg = new Msg(message, yesAsDefault);
                                    ThreadEvent.await();
                                    response = msg.getResponse();
                    
                                }
                            }).start();
                        }
                        public boolean getResponse() {
                            DisplayManager.setCurrent(displayable);
                            return response;
                        }
                    }
                    The Msg class that is a simple alert with Yes/no response:
                    import javax.microedition.lcdui.Alert;
                    import javax.microedition.lcdui.AlertType;
                    import javax.microedition.lcdui.Command;
                    import javax.microedition.lcdui.CommandListener;
                    import javax.microedition.lcdui.Displayable;
                    
                    public class Msg implements CommandListener {
                    
                        private Alert alert;
                        private Command cmdYES;
                        private Command cmdNO;
                        private boolean response;
                        
                    
                        public Msg(String message, boolean yesAsDefault) {
                            
                            if (yesAsDefault) {
                                cmdYES = new Command("Ναι", Command.OK, 0);
                                cmdNO = new Command("Όχι", Command.CANCEL, 0);
                            } else {
                                cmdYES = new Command("Ναι", Command.CANCEL, 0);
                                cmdNO = new Command("Όχι", Command.OK, 0);
                            }
                            alert = new Alert("ΕΡΩΤΗΣΗ", message, null, AlertType.WARNING);
                            alert.addCommand(cmdYES);
                            alert.addCommand(cmdNO);
                            alert.setCommandListener(this);
                            alert.setTimeout(Alert.FOREVER);
                    
                            DisplayManager.setCurrent(alert);
                        }
                    
                        public void commandAction(Command c, Displayable d) {
                            if (c == cmdYES) {
                                this.response = true;
                                ThreadEvent.signal();
                            } else if (c == cmdNO) {
                                this.response = false;
                                ThreadEvent.signal();
                            }
                        }
                    
                        public boolean getResponse(){
                            return response;
                        }
                    The ThreadEvent class creates a synchronized object lock between threads.

                    The same issue also comes forward in another method where I want to import records and I want to select a file using a file browser. I want the "code" to wait until a file is selected.
                    Both the example above and the filebrowser should implement a commandListener so that the call to get the response in the first case and the fileURL in the second is minimum, to be able to use inside and if clause or a file parser.

                    Thank you in advance!
                    • 7. Re: Method of class gets called first, then constructor ???
                      796440
                      Dimitrios wrote:
                      hi jverd,

                      I know this is more than confusing code. It's bad code with unnecessary complexity, however it is the only way I found to have a class wait for input from another
                      This makes no sense to me. There certainly are ways to have one class "wait for input from another" (whatever specifically you mean by that) without making the code all muddled and hard to read.
                      (In this case the if clause evaluation should halt until the response boolean (from Msg actually, passed to Message in the example) is returned.
                      Sounds like you want multiple threads, and either wait/notifyAll or an inter-thread communication class provided in java.util.concurrent.
                      I know that the constructor is ALWAYS executed first upon instantiation, however when stepping through the code it seems that the method is returned first (thus the return boolean is always false).
                      There's no way that the getResponse in the same line as the "new" is called before the constructor. The other getResponse is called in a new thread that's launched from within the c'tor.
                      • 8. Re: Method of class gets called first, then constructor ???
                        802645
                        >
                        This makes no sense to me. There certainly are ways to have one class "wait for input from another" (whatever specifically you mean by that) without making the code all muddled and hard to read.>
                        I believe you 've said it just below. Multiple threads! (If you have any other in mind let me know).
                        I think that the code I presented above serves a good example of that. When I call the deleteRecord() method I want to first display an alert, wait for the alert to respond (return a boolean value based on the command selected) and then according to the return value continue to the code inside the if clause. In addition I want the alert class to be reusable for other cases (with the same yes/no commands).
                        jverd wrote: Sounds like you want multiple threads, and either wait/notifyAll or an inter-thread communication class provided in java.util.concurrent.
                        java.util.concurrent doesn't exist in CLDC 1.1 / MIDP 2.0 I am targeting. wait / notify are implemented in the ThreadEvent class as I described above. It holds an object lock and has a lock method and a release method. Works like a charm without having to create new object instances all the time. It is roughly a wrapper class that allows me to halt execution of a thread with ThreadEvent.await() and in the second thread once updated the value I want call ThreadEvent.signal() to return execution to the calling thread. In the example this is what happens in the Message class.
                        jverd wrote: There's no way that the getResponse in the same line as the "new" is called before the constructor. The other getResponse is called in a new thread that's launched from within the c'tor.
                        That's also what I think. I will check for the third time and get back to you on that.

                        One extra pointer:
                        In the commandListerner implementation in the visual class, I have a command that says "Delete Record". At the previous version of my app, I had that command, switch displayable to an Alert with yes/no commands and then if the command selected was YES, proceed with the rest of the record deletion code.
                        That class was designed in Netbeans using the visual designer and worked like a charm without having to resort to multithreading. The same commandListener was used for both the delete command and the yes/no commands (Both were in the same class). But that way beats any chances of reusing the code (the alert part).

                        To best describe what I want allow me to explain.

                        In the if clause of deleteRecord() I want to:
                        1. Instantiate an Alert with yes/no commands (and get the response once selected).
                        2. Display the Alert.
                        3. Wait for a command to be selected.
                        4. Return the command result (a boolean) to the if clause.
                        5. Evaluate the if clause and if true > continue execution.

                        I believe these are achieved as:
                        1. new AlertClassWithCommandListener(String args[]) .getResponse()
                        2. switchDisplayable inside AlertClassWithCommandListener
                        3. Create new thread to instantiate 1. And create object lock until the commandListener implemented inside AlertClassWithCommandListener sets a private boolean.
                        4. Return the method's getResponse() value to the if clause (from the private boolean set above) and release the object lock.
                        5. Evaluate the if clause based on the getResponse() value.

                        Hope this clears things out.

                        PS. The case with this alert with yes/no commands is not the only case I want to have code wait on some value returned from another class. As I said this will be also used to get a filename from a browser to parse the file selected, an inputbox style TextBox to process user input, etc...

                        The reason for all this trouble is that eg the deleteRecord() method will be called on many occasions for different recordsets and I want to write reusable code, as the visual designer in Netbeans although wonderful at first, sets many limitations and created huge class files that is difficult to maintain, not to mention code modularity.
                        • 10. Re: Method of class gets called first, then constructor ???
                          762917
                          I think youre complicating your life with so many classes. if you just want to ask if should it proceed or not, i did something like that using a Form with two commands "yes" and "no" as the answers.
                          // when you need to make the question, you call it
                          switchDisplayable(null,getQuestionScreen());
                          .
                          .
                          .
                          // This is the method that returns the question screen
                          public Form getQuestionScreen(){
                                  if(questionScreen == null){
                                      questionScreen = new Form("Your Title");
                                      question = new StringItem("","\n\Your Question?");
                          
                                      questionScreen.setCommandListener(this);
                          
                                      questionScreen.append(question);
                          
                                      questionScreen.addCommand(CMD_SI);
                                      questionScreen.addCommand(CMD_NO);
                                  }
                                  return questionScreen;
                              }
                          .
                          .
                          .
                          // To handle the answer in the commandAction method
                          if(displayable == questionScreen){
                                      if(command == CMD_SI){
                                          // Here what you want to di if YES
                                          switchDisplayable(null,getProductScreen());
                                      }else if(command == CMD_NO){
                                          // Here what you want to di if NO
                                          exitMIDlet();
                                      }
                                  }
                          I think this is more easy instead of use threads and classes. The purpose is very simple.
                          • 11. Re: Method of class gets called first, then constructor ???
                            802645
                            This is exactly as I have it currently implemented. However as I said above, it is being used the same way for over 40 different cases, which creates 40 unnecessary code fragment duplicates. I also stated that I want the command listener and the whole form to be in another class to be generalized, to be used whenever I want to get a yes/no response from a user.
                            • 12. Re: Method of class gets called first, then constructor ???
                              762917
                              In that case just have to modified it a little. Instead of call a Form method, you instanciate a Form class like this
                              switchDisplayable(null,new QuestionScreen(this));
                              .
                              .
                              And this is the Form class
                              public class questionForm extends Form implements CommandListener {
                              
                                  public questionForm(MIDlet outScreen){ // here you receive the outside midlet
                                      super("Question Form");
                                      this.outScreen = outScreen;
                                      public boolean flag; // the variable to use to compare if it proceed or not
                              
                                      exit = new Command("Exit",Command.EXIT,0);
                                      // you also have to create the yes, no commands
                              
                                      this.addCommand(exit);
                                      this.addCommand(yes);
                                      this.addCommand(no);
                                      this.setCommandListener(this);
                                      Display.getDisplay(outScreen).setCurrent(this);
                                  }
                              
                                  public void commandAction(Command c, Displayable d){
                                      if(c.equals(exit)){
                                          outScreen.notifyDestroyed();
                                      }
                                      if(c.equals(yes)){
                                          flag = true;
                                      }
                                      if(c.equals(no)){
                                          flag = false;
                                      }
                                  }
                              }
                              This way you can instanciate it each time you have to.
                              • 13. Re: Method of class gets called first, then constructor ???
                                802645
                                However instantiating questionForm from switchDisplayable would:
                                1) Not allow me to refer to that object instance to get the flag boolean.
                                2) Would not stop code execution after the switchDisplayable waiting for the flag to be set. In my case the if clause that should be evaluated after the flag being set.


                                Trying to make it happen using Threads as in my previous posts, I realized that even synchronization and object locking won't stop code that is after the thread.start() method.
                                The code always runs until the method returns.
                                The only way to make code wait is to implement all necessary code inside the new thread and return the method right after thread.start().