2

I'm working in java me. I'm trying to switch between visual designs using ok Commands and back Commands. I have a form displayable which I named formA in my main class A.java and a formB in another class B.java . I used an ok Command in formA which on selection, is supposed to take the user to formB.

I created a reference to B.java in my main class A.java constructor

B b;

 // A.java constructor
public A() {
    b = new B(this);
}

now I could call the getFormB method from my commandAction in formA. Then I added a backCommand which is supposed to take me back to formA in A.java and I tried creating a reference in B.java same way I did in A.java but I get a SecurityException MIDletManager ERROR at runtime. I was adviced to add an A attribute to my B class and receive the instance as a constructor parameter so I can call the getFormA() method to switch to formA in A.java

A a;

B(A a) {
    this.a = a;
}

in command action I did ds on the backCommand: switchDisplayable ( null , a.getFormA()); This compiled, but at runtime on hitting the BACK key from formB I get java/lang/NullPointerException.

Can anyone tell me why this happended and how to fix it please. All I'm trying to acheive is the backCommand to take the user back to formA from formB

degee
  • 173
  • 2
  • 11

1 Answers1

3

If your A class extends Form or your A class is Displayable, then in the Back command, you can just tell switchDisplayable(null, a).

If your A class is not a Form, then make sure your A class has the following methods:

public Form getFormA() {
   return ...;  // return the `Form` here so you will not get NullPointerException
}

UPDATE:

If you're using NetBeans, you can open Flow tab and drag backCommand from formB to formA. NetBeans will generate the required code for you.

enter image description here

If you code by hand, then it will looks like the following:

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class ExampleMidlet extends MIDlet {

    private Display display;
    private Form formA;
    private Form formB;
    private Command formA_next;
    private Command formB_back;

    public void startApp() {
        if (display==null) {
            display = Display.getDisplay(this);

            formA = new Form("Form A");
            formA_next = new Command("Next", Command.SCREEN, 0);
            formA.addCommand(formA_next);
            formA.setCommandListener(new CommandListener() {

                public void commandAction(Command c, Displayable d) {
                    if (c==formA_next) {
                        display.setCurrent(formB);
                    }
                }
            });

            formB = new Form("Form B");
            formB_back = new Command("Back", Command.BACK, 0);
            formB.addCommand(formB_back);
            formB.setCommandListener(new CommandListener() {

                public void commandAction(Command c, Displayable d) {
                    if (c==formB_back) {
                        display.setCurrent(formA);
                    }
                }

            });
        }        
        display.setCurrent(formA);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

I don't know how you code your Form, but it seems that a is null. Maybe you can show me the full code. Passing this in constructor is generally not recommended. By the way, you still need a 'main' class that extends MIDlet right? Then there will be 3 classes, such as:

ExampleMiddlet.java (this is where you put your MIDlet lifecycle, such as startApp(), pauseApp(), etc):

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class ExampleMidlet extends MIDlet {

    private Display display;
    private Form formA, formB;    

    public void startApp() {
        if (display==null) {
            display = Display.getDisplay(this);
            formA = new FormA(this);
            formB = new FormB(this);
        }        
        display.setCurrent(formA);
    }

    public Form getFormA() {
        return formA;
    }

    public Form getFormB() {
        return formB;
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }
}

FormA.java (this is where you put the content of your Form):

import javax.microedition.lcdui.*;

public class FormA extends Form {

    private Command cmdNext;    

    public FormA(final ExampleMidlet midlet) {
        super("Form A");        
        append("This is form A.");
        cmdNext = new Command("Next", Command.SCREEN, 0);        
        addCommand(cmdNext);
        setCommandListener(new CommandListener() {

            public void commandAction(Command c, Displayable d) {
                Display.getDisplay(midlet).setCurrent(midlet.getFormB());
            }
        });
    }

}

FormB.java (this is where you put the content of your Form):

import javax.microedition.lcdui.*;

public class FormB extends Form {

    private Command cmdBack;

    public FormB(final ExampleMidlet midlet) {
        super("Form B");        
        append("This is form B.");
        cmdBack = new Command("Back", Command.SCREEN, 0);        
        addCommand(cmdBack);
        setCommandListener(new CommandListener() {

            public void commandAction(Command c, Displayable d) {
                Display.getDisplay(midlet).setCurrent(midlet.getFormA());
            }

        });
    }

}
jocki
  • 1,728
  • 16
  • 26
  • There's a getFormA() method in A.java and it returns formA this is why I don't understand where the NullPointerException comes from The first idea also did not work. Throws the same exception – degee Jan 23 '13 at 07:49
  • Thanks a lot for taking ur time to reply me. Yes I'm on Netbeans, the drag and drop feature from the flow view works only when the forms are in the same java file not when they're in separate java files. Pls try using 2 java files and place forms in both, then try switching between them using commands. This is what I'm trying to achieve. Why I decided to work with separate java files is because my App is going to have many forms and I wouldn't like to put all in a single java file so they can easily be managed. – degee Jan 23 '13 at 12:58
  • If you use 2 java files to represent a `Form`, where do you put `MIDlet` lifecycle methods (`startApp()`, `pauseApp()`, and `destroyApp()`)? One `MIDlet` generally represent one application. I have updated the last code snippet above, 3 Java files: 1 for `MIDlet` and 2 child of `Form` (`FormA` and `FormB`). – jocki Jan 23 '13 at 13:59
  • Now u totally understand me. Thank you for the insight. I didn't think of the midlet lifecycle. I'm going to try and work it out using ur example above. I'll drop feedback. – degee Jan 23 '13 at 14:34
  • Pls can you guide me on using the Netbeans VMD to create my Classes(Main class, formA, formB etc) and switch between them when my app demands. I tried coding by hand using ur example but I always get an invalid application. . – degee Jan 25 '13 at 11:50
  • Try to make sure you are adding MIDlet class by right click on the project, select New, MIDlet... The other classes are plain Java Class.. MIDP run in limited hardware resources, adding more class mean more overhead and not a best practise. I don't know how to use VMD, but I found this http://wiki.netbeans.org/FAQHowToSplitVisualMobileDesig. – jocki Jan 25 '13 at 18:12
  • I'll try that. I've come across that link b4, I don't want to start going into the errors I get. I'm pretty sure it all has to do with basic language stuff. You've been of great help so far, makes me want to do more. I appreciate – degee Jan 26 '13 at 10:33