首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 屏幕切換實戰模式:Display.setCurrent()、父子屏幕引用傳遞與命令導航完整示例

     編輯:J2ME

核心機制

J2ME 界面導航核心是 Display.setCurrent(Displayable next)。每個 MIDlet 擁有唯一 Display 實例 (由 Display.getDisplay(this) 獲取),所有顯示對象 (Form、List、TextBox、Alert、Canvas) 均實現 Displayable 接口。

設計模式:父屏幕引用傳遞實現「返回」導航

關鍵思想:**子屏幕構造時接收父屏幕的 Displayable 引用,返回時直接 setCurrent(parent)**。

完整雙屏幕切換示例

MainMIDlet.java - 主屏幕

package fancy.test;

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

public class MainMIDlet extends MIDlet implements CommandListener {
    private Display display;
    private Form mainForm;
    private Command okCommand = new Command("OK", Command.OK, 1);
    private StringItem welcomeItem = new StringItem("Main Screen", "Welcome!! ~_~");
    private Form nextScreen;  // 子屏幕實例引用

    public MainMIDlet() {
        mainForm = new Form("Welcome!!");
        mainForm.append(welcomeItem);
        mainForm.addCommand(okCommand);
    }

    protected void startApp() throws MIDletStateChangeException {
        display = Display.getDisplay(this);
        mainForm.setCommandListener(this);
        display.setCurrent(mainForm);
    }

    protected void pauseApp() {}
    protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {}

    public void commandAction(Command c, Displayable d) {
        if (c == okCommand) {
            // 關鍵:將當前 Display 和 父屏幕 Form 傳給子屏幕
            nextScreen = new NextScreen(display, mainForm);
            display.setCurrent(nextScreen);
        }
    }
}

NextScreen.java - 子屏幕 (繼承 Form)

package fancy.test;

import javax.microedition.lcdui.*;

public class NextScreen extends Form implements CommandListener {
    private Display display;
    private Displayable parentScreen;  // 父屏幕引用
    private Command backCommand = new Command("BACK", Command.BACK, 1);
    private StringItem infoItem = new StringItem("Second Screen", "~_~");

    public NextScreen(Display d, Displayable parent) {
        super("Next Screen");
        this.display = d;
        this.parentScreen = parent;
        append(infoItem);
        addCommand(backCommand);
        setCommandListener(this);
    }

    public void commandAction(Command c, Displayable d) {
        if (c == backCommand) {
            // 一鍵返回父屏幕
            display.setCurrent(parentScreen);
        }
    }
}

關鍵代碼解析

代碼行作用
nextScreen = new NextScreen(display, mainForm);子屏幕持有 Display (用於 setCurrent) 和父屏幕引用 (用於返回)
display.setCurrent(nextScreen);切換顯示到子屏幕
display.setCurrent(parentScreen);在子屏幕 BACK 命令中返回父屏幕

進階:多層級導航棧管理

為支持「主菜單 → 子菜單 → 詳情 → 返回子菜單 → 返回主菜單」任意深度導航,建議在 MIDlet 中維護一個 Vector 棧:

private Vector screenStack = new Vector();  // 存儲 Displayable

// 進入新屏幕
public void pushScreen(Displayable screen) {
    Displayable current = display.getCurrent();
    if (current != null) screenStack.addElement(current);
    display.setCurrent(screen);
}

// 返回上一屏幕
public void popScreen() {
    if (screenStack.size() > 0) {
        Displayable prev = (Displayable) screenStack.lastElement();
        screenStack.removeElementAt(screenStack.size() - 1);
        display.setCurrent(prev);
    }
}

常見錯誤與避坑

  • 忘記 setCommandListener:子屏幕未註冊監聽器,按鍵無響應
  • 重複創建子屏幕實例:每次跳轉 new NextScreen() 會丟失用戶輸入狀態,建議緩存實例或在構造函數中恢復狀態
  • Display 為 null:startApp 前調用 setCurrent,確保 display = Display.getDisplay(this) 已執行
  • 內存洩漏:長棧未釋放不再需要的屏幕對象,及時從 Vector 移除並置 null

運行效果展示

主屏幕:顯示「Welcome!! ~_~」,軟鍵「OK」
MainMIDlet 截圖

子屏幕:顯示「Second Screen ~_~」,軟鍵「BACK」
NextScreen 截圖

總結

掌握 Display.setCurrent() + 父屏幕引用傳遞 + Command 導航 這一核心模式,即可構建任意深度的 J2ME 應用界面流程。配合導航棧模式,可實現類似 Android Activity/Fragment 的完整頁面管理體驗。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved