Команда J2ME Back — возврат к предыдущему экрану


Я застрял, пытаясь понять, как создать команду возврата на предыдущий экран.
Страница, на которую я пытаюсь вернуться, имеет не форму, а список, но когда я устанавливаю
прослушиватель команды «назад» в список, кажется, что он генерирует исключение нулевого указателя.

Вот мой основной класс

import java.util.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

/**
 * 
 */
public class CalFrontEnd extends MIDlet implements CommandListener 
{
    private Display display;
    protected List list = new List("Please Select a Option", List.IMPLICIT);
    private Command select = new Command("Select", Command.SCREEN, 1);
    private Command exit = new Command("Exit", Command.EXIT, 2);
    private Command save = new Command("Save,", Command.SCREEN, 2);
    private DateField calendar;


    /**
     * 
     */
    public CalFrontEnd() 
    {
        display = Display.getDisplay(this);   
        list.append("Select Date", null);
        list.append("Add Events", null);
        list.append("Remove Events", null);
        list.append("Browse Events", null);
        list.addCommand(select);
        list.addCommand(exit);
        list.setCommandListener(this);
    }


    /**
     * Start Application
     */
    public void startApp() 
    {
        display.setCurrent(list);
    }


    /**
     * Pause Application Method
     */
    public void pauseApp() 
    {}


    /**
     * Destroy Application Method
     */
    public void destroyApp(boolean unconditional)
    {}


    /**
     * 
     * @param command
     * @param displayable 
     */
    public void commandAction(Command command, Displayable displayable) 
    {
        if (displayable == list) {
            if (command == List.SELECT_COMMAND) {
                switch (list.getSelectedIndex()) {
                    case 0: // select Date
                        SelectDate myDate = new SelectDate(display);
                        myDate.BuildCalendar();
                        break;
                    case 1: //add Events
                        AddEvents myAEvents = new AddEvents(display);
                        myAEvents.BuildAddEvents();
                        break;
                    case 2: //Remove Events
                        RemoveEvents myREvents = new RemoveEvents(display);
                        myREvents.BuildRemoveEvents();
                        break;
                    case 3: //Browse Events
                        BrowseEvents myBEvents = new BrowseEvents(display);
                        myBEvents.BuildBrowseEvents();
                        break;
                }
            } else if (command == exit) {
                destroyApp(false);
                notifyDestroyed();
            }
        }         
    } 
}

И это класс, на котором я пытаюсь использовать кнопку «Назад».

import java.util.*;
import javax.microedition.lcdui.*;


/**
 * 
 */
public class SelectDate extends CalFrontEnd implements CommandListener 
{
    private DateField calendar;
    private Form form = new Form("Please Select a Date");
    private Command select = new Command("Select", Command.SCREEN, 1);
    private Command back = new Command("Back", Command.BACK, 2);
    private Command save = new Command("Save,", Command.SCREEN, 2);
    private Display display;


    /**
     * 
     */
    public SelectDate(Display display)
    {
        this.display = display;
    }


    /**
     * 
     */
    public void BuildCalendar()
    {
        calendar = new DateField("Date In :", DateField.DATE, TimeZone.getTimeZone("GMT"));
        form.append(calendar);
        form.addCommand(back);
        form.setCommandListener(this);
        display.setCurrent(form);
    }  


    /**
     * 
     * @param command
     * @param displayable 
     */
    public void commandAction(Command command, Display display)
    {
        if (command == back)
        {
            display.setCurrent(list);
        }
    }
}

person Skeng    schedule 03.05.2012    source источник


Ответы (3)


Неуместное использование наследования привело вас к неприятностям. Посмотрите, есть поле list в классе SelectDate, но оно не видно в коде, потому что оно унаследовано от суперкласса (на самом деле все ваши проблемы начинаются с extends CalFrontEnd и protected List list).

Когда вы создаете экземпляр SelectDate (new SelectDate(display)), это поле инициализируется null, и после этого вы никогда его не меняете. Вам трудно это заметить, потому что само объявление list скрыто в другом файле в суперклассе. И, что еще больше усложняет ситуацию, компилятор не может вам здесь помочь, потому что поле ему видно, и он считает, что все в порядке.

  • Знаете, это только начало ваших проблем, связанных с чрезмерным использованием наследования. Дальше по дороге ждут новые головные боли. Подумайте, например, что произойдет, если вы случайно удалите или переименуете commandAction в SelectDate? Компилятор подумает, что все в порядке — просто потому, что у суперкласса тоже есть этот метод. Вы только заметите, что что-то пошло не так каким-то таинственным образом, когда вы запустите код и обнаружите, что команды на экране выбора даты перестают отвечать или начинают делать странные вещи. На самом деле было бы безопаснее скрыть CommandListener для обоих классов, чтобы избежать подобных ошибок, но это обсуждалось в другом вопросе.< /под>

Я настоятельно рекомендую удалить extends CalFrontEnd из SelectDate. Это поможет компилятору помочь вам найти различные логические проблемы в вашем коде.

Что касается списка, отображаемого командой Back, вы можете, например, передать его как дополнительный параметр конструктора, как показано ниже:

public class SelectDate implements CommandListener // drop "extends CalFrontEnd"
{
    // ...
    private Display display;
    private List list; // add the field for the list


    public SelectDate(Display display, List list) // add list as parameter
    {
        this.display = display;
        this.list = list; // initialize field
    }
    // ... commandAction code will get the right "list" now
}
person gnat    schedule 04.05.2012

Есть ряд проблем, связанных с вашим кодом.

Один комар уже упоминал (Удалить extends CalFrontEnd в SelectData классе).

Во-вторых, вы не вызываете команду select в commandAction вашего кода (вызываемая вами команда — List.SELECT_COMMAND, а не select). Поэтому измените if (command == List.SELECT_COMMAND) на if (command == select).

В-третьих, документация commandAction в CommandListener объявляет второй параметр как Displayable, в то время как вы объявляете его с помощью Display.

person Ameer Moaaviah    schedule 07.05.2012

ошибка в том, что нет переменной с именем list, однако решение состоит в том, чтобы просто изменить код под кнопкой «Назад» с

display.setCurrent (список)

to

display.setCurrent(CalFrontEnd.list)

person Abdu Ssekalala    schedule 04.05.2012