Display.setCurrent() reads null on calls to screen
Developing a UI form that requires the user to input text as a title for something that is added to the list on the form.
Here's a pseudo version of the code:
publicclass mainFormextends Formimplements CommandListener{
...
publicvoid mainForm(...){
...
setCommandListener(this);
...
}
...
publicvoid commandAction(Command c, Displayable d)
{
if (c == CMD_1)
...
if (c == CMD_2){
TextInput textInput =new TextInput(null, this, display);
display.setCurrent(textInput);// stops working here
choiceGroup.append(textInput.getString(),null);// this line works, if the previous is commented
}
}
}
where
publicclass TextInputextends TextBoximplements CommandListener{
...
public TextInput(String title, mainForm parent, Display display){
super(title, null, 50, TextField.ANY);
...
setCommandListener(this);
}
publicvoid commandAction(Command c, Displayable d){
if (c == CMD_OK){
...
display.setCurrent(parent);
}
if (c == CMD_CANCEL){
...
display.setCurrent(parent);
}
}
}
When I call display.setCurrent(textInput) from the mainForm, the program returns a nullPointerException. The textInput is created and works, but never displays because of the same exception. Is there a problem with the way I'm calling the functions or structuring the program?
Message was edited by:
quote
[2875 byte] By [
quotea] at [2007-11-27 11:09:54]

# 1
are you sure that display is not null?
# 2
hi i am not sure if i understand what you are doing? but you cannot set display to the textfield....
in your class that implements midlet set display to a form class or extend form and set to this. inside that form class create a new textfield and add it to the form../fg
EDIT: well i was a bit bored and thought i could fix a quick example for you...
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyClient extends MIDlet {
private Display display;
// Views
private MainScreen mainScreen;
private SecondScreen secondScreen;
public MyClient () throws Exception {
// Declare display
display = Display.getDisplay(this);
// Init Screens
mainScreen = new MainScreen(this);
secondScreen = new SecondScreen(this);
}
public void startApp() {
setMainScreen ();
}
public void pauseApp() {
// Nothing to do ...
}
public void destroyApp(boolean unconditional) {
}
// Setters
public void setMainScreen () {
display.setCurrent(mainScreen);
}
public void setSecondScreen () {
display.setCurrent(secondScreen);
}
// Getter methods
public Display getDisplay() {
return display;
}
public MainScreen getMainScreen() {
return mainScreen;
}
public SecondScreen getSecondScreen() {
return secondScreen;
}
}
class MainScreen extends Form implements CommandListener {
// The Main Driver Midlet Class
private MyClient myClient;
// TextField
private TextField myTextField;
// Choice Group
private ChoiceGroup myChoiceGroup;
// commands
private Command okCommand;
private Command exitCommand;
public MainScreen(MyClient m) {
//create form
super("Main Form");
// Set MyClient
myClient = m;
okCommand = new Command("Ok", Command.SCREEN, 1);
exitCommand = new Command("Exit", Command.CANCEL, 1);
// Create new textfields
myTextField = new TextField ("Title", "", 50, TextField.ANY);
// Create ChoiceGroups
String values[] = {"Zero", "One","Two"};
myChoiceGroup = new ChoiceGroup("Label ", 4, values, null);
// Add the components to the form
append (myTextField);
append (myChoiceGroup);
// Set the commands for bottom of screen
addCommand (okCommand);
addCommand (exitCommand);
setCommandListener(this);
}
public void commandAction(Command c, Displayable d)
{
if (c == okCommand){
// Update the info in the second screen
myClient.getSecondScreen().update();
// Goto the second screen
myClient.setSecondScreen();
} else if (c == exitCommand) {
// exit the app
myClient.destroyApp(false);
myClient.notifyDestroyed();
}
}
public String getMyTextField(){
System.out.println(myTextField.getString());
return myTextField.getString();
}
public int getMyChoiceGroup(){
return myChoiceGroup.getSelectedIndex();
}
}
class SecondScreen extends Form implements CommandListener {
// The Main Driver Midlet Class
private MyClient myClient;
// TextField
private TextField myTextField;
private TextField secondTextField;
// commands
private Command backCommand;
public SecondScreen(MyClient m){
//create form
super("Second Form");
// Set MyClient
myClient = m;
// Init Command
backCommand = new Command("Back", Command.CANCEL, 1);
// Create new textfields
myTextField = new TextField ("TextField Result", "", 20, TextField.ANY);
secondTextField = new TextField ("ChoiceGroup Option#", "", 20, TextField.ANY);
append(myTextField);
append(secondTextField);
// Set the commands for bottom of screen
addCommand (backCommand);
setCommandListener(this);
}
public void update(){
myTextField.setString(myClient.getMainScreen().getMyTextField());
secondTextField.setString(""+myClient.getMainScreen().getMyChoiceGroup());
}
public void commandAction(Command c, Displayable d) {
if (c == backCommand) {
myClient.setMainScreen();
}
}
}
try this its very basic but i think it may help..... also i would recommend splitting this up into different classes and packages../fg
Message was edited by:
freddiegold
# 3
So I can't call Display.setCurrent() except in the MIDlet class?
I am trying to make a reusable Form class that has a list and a "special" interface (works already), but I can't get just this part to work. I need it to open a TextBox so the user can type in whatever. If Forms are not allowed to change the display using Display.setCurrent(), I'll just find another way of getting user input (like appending a TextField to the Form).
quotea at 2007-7-29 13:38:20 >

# 4
i am not fully getting what you mean... i think within reason you can do what ever you like.... one thing i am not sure about is setting the display to something that is not a container i.e. a form/canvas....
As a textfield is a item, items need to live in a form....therefore just put textfield in the form(the only place to put i think.) and set display to form....
EDIT: sorry and you can call Display.setCurrent() where ever you want but i think it needs to refer to the display created in the main class that implements MIDlet.. (at least this is what i have been doing). I am not 100% maybe google is needed..sorry.../fg
Message was edited by:
freddiegold
# 5
Thanks for all the help freddiegold. I don't think the TextBox is a container, but it's actually a Display (under Screen) just like Alerts, Lists, and Forms. The TextField is an Item that I know can be appended to the Form, but if I do that, it is not multi-line like the TextBox would be.
My question regards the ability to initialize and switch to a TextBox from a Form, without necessarily initializing the TextBox in the parent MIDlet: if it is possible and how to accomplish that.
quotea at 2007-7-29 13:38:21 >

# 6
> TextField is an Item that I know can be appended to the Form, but if I do that, it is not multi-line
in my emulator a textfield is always on one line(mpowerplayer), but on my SE phone a textfield turns into a multi-line automatically if you specify the max characters are more than one line, then as you enter chars it auto grows...
but of course if you implement a TextBox just as a form or list you can switch between them... i still dont know if i get what you mean but i have attached some of your code a bit editted....
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class MyClient extends MIDlet {
private Display display;
// Views
private MainScreen mainScreen;
private SecondScreen secondScreen;
public MyClient () throws Exception {
// Declare display
display = Display.getDisplay(this);
// Init Screens
mainScreen = new MainScreen(this);
secondScreen = new SecondScreen(this);
}
public void startApp() {
setMainScreen ();
}
public void pauseApp() {
// Nothing to do ...
}
public void destroyApp(boolean unconditional) {
}
// Setters
public void setMainScreen () {
display.setCurrent(mainScreen);
}
public void setSecondScreen () {
display.setCurrent(secondScreen);
}
// Getter methods
public Display getDisplay() {
return display;
}
public MainScreen getMainScreen() {
return mainScreen;
}
public SecondScreen getSecondScreen() {
return secondScreen;
}
}
class MainScreen extends Form implements CommandListener {
// The Main Driver Midlet Class
private MyClient myClient;
// TextField
private TextField myTextField;
// Choice Group
private ChoiceGroup myChoiceGroup;
// commands
private Command okCommand;
private Command exitCommand;
public MainScreen(MyClient m) {
//create form
super("Main Form");
// Set MyClient
myClient = m;
okCommand = new Command("Ok", Command.SCREEN, 1);
exitCommand = new Command("Exit", Command.CANCEL, 1);
// Create new textfields
myTextField = new TextField ("Title", "", 200, TextField.ANY);
// Create ChoiceGroups
String values[] = {"Zero", "One","Two"};
myChoiceGroup = new ChoiceGroup("Label ", 4, values, null);
// Add the components to the form
append (myTextField);
append (myChoiceGroup);
myClient.getDisplay().setCurrentItem(myTextField);
// Set the commands for bottom of screen
addCommand (okCommand);
addCommand (exitCommand);
setCommandListener(this);
}
public void commandAction(Command c, Displayable d)
{
if (c == okCommand){
// Goto the second screen
myClient.setSecondScreen();
} else if (c == exitCommand) {
// exit the app
myClient.destroyApp(false);
myClient.notifyDestroyed();
}
}
public String getMyTextField(){
System.out.println(myTextField.getString());
return myTextField.getString();
}
public int getMyChoiceGroup(){
return myChoiceGroup.getSelectedIndex();
}
}
class SecondScreen extends TextBox implements CommandListener {
// The Main Driver Midlet Class
private MyClient myClient;
// commands
private Command backCommand;
public SecondScreen(MyClient m){
//create form
super("Second Form", "text goes here", 300, 0);
// Set MyClient
myClient = m;
// Init Command
backCommand = new Command("Back", Command.CANCEL, 1);
// Set the commands for bottom of screen
addCommand (backCommand);
setCommandListener(this);
}
public void commandAction(Command c, Displayable d) {
if (c == backCommand) {
myClient.setMainScreen();
}
}
}
hope its what you mean.../fg
# 7
Thanks for all the help, but it isn't exactly what I mean. I am trying to switch the display from a method inside the Form.
Display.setSelectedItem(Item) also doesn't work from inside a Form method. A nullPointerException is thrown when I use it.
Any ideas on why this is happening?
quotea at 2007-7-29 13:38:21 >
