Interval.cz
J2ME v p°φkladech, dφl t°etφ - tvo°φme menu II

U₧ jsme si ukßzali, jak se tvo°φ ·vodnφ obrazovka midlet∙ a takΘ jak se tvo°φ nabφdka neboli menu pomocφ vysoko·rov≥ov²ch komponent. Nynφ se nauΦφme tvo°it menu pomocφ nφzko·rov≥ov²ch komponent se vÜφm, co k tomu pat°φ.

Jak to funguje a co tφm dosßhneme?

Nynφ u₧ je nßm jasnΘ jak fungujφ vysoko·rov≥ovΘ komponenty. Jejich zobrazenφ je zßvislΘ na konkrΘtnφ implementaci Javy v mobilnφm telefonu. Na jednu stranu nßm to uÜet°φ hodn∞ prßce a starostφ s tφm, aby vÜe fungovalo opravdu korektn∞ a bez zßdrhel∙, ale na druhou stranu nßs to celkem omezuje z hlediska kreativity a designu. Menu je sice funkΦnφ, ale je stejnΘ jako v ostatnφch aplikacφch na stejnΘm typu mobilnφho telefonu, kde autor pou₧il stejn²ch komponent. Pokud tou₧φte po osobitΘm vzhledu svΘ aplikace, musφte se pustit do nφzko·rov≥ov²ch komponent.

Tento p°φstup k tvorb∞ menu spoΦφvß v jeho vytvo°enφ tak°φkajφc od pφky. Pokud zvolφte tuto cestu, je t°eba myslet na to, ₧e mßte prakticky neomezenΘ mo₧nosti, co se t²Φe vzhledu a funkcionality menu, nesmφte ale zapomφnat, ₧e na vaÜi hlavu padß odpov∞dnost za jeho kompletnφ funkcionalitu. Je t°eba postarat se o ka₧diΦk² detail, by¥ by to m∞l b²t jen posun kurzoru mezi jednotliv²mi polo₧kami. Laicky °eΦeno, budete se starat o vykreslenφ ka₧dΘho pixelu "ruΦn∞". Budete kreslit jednotlivΘ polo₧ky menu, ukazatel aktußln∞ zvolenΘ polo₧ky, kter² budete zobrazovat tak, aby jeho poloha korespondovala s u₧ivatelsk²m vstupem. Budete "hlφdat" klßvesy tak, aby p°i stisku zaznamenal u₧ivatel po₧adovanou akci.

Na prvnφ pohled to vypadß opravdu nßroΦn∞, ale opak m∙₧e b²t pravdou. Poj∩me se o tom p°esv∞dΦit. Pro nßzornΘ srovnßvßnφ lehce navß₧eme na menu z p°edeÜlΘ kapitoly a vytvo°φme menu se stejnou funkcionalitou, ale s jin²m vzhledem - v²sledek budete moci srovnat sami.

Nejprve pßr obrßzk∙...

NovΘ menu bude mφt velikost 101x64 pixel∙, vejde se tedy na vÜechny telefony, kterΘ majφ displej odpovφdajφcφ velikosti. Pou₧it² podklad bude Φernobφl², majitelΘ barevn²ch mobil∙ si vÜak mohou vytvo°it podklad barevn² a bez problΘm∙ ho v naÜem p°φkladu pou₧φt.

Jako prvnφ vytvo°φme podklad menu. Bude bu∩ Φernobφl² nebo barevn², to podle dispozic mobilnφho telefonu. My si vytvo°φme ob∞ varianty v jednΘ aplikaci. Midlet toti₧ dokß₧e rozpoznat jestli je zobrazen na barevnΘm nebo ΦernobφlΘm displeji, Φeho₧ vyu₧ijeme a podle toho zobrazφme Φernobφl² nebo barevn² podklad:

Menu.png
Menu 101 x 64, formßt PNG, Φernobφl².
Menu.png barevn²
Menu 101 x 64, formßt PNG, barevn².

Tyto obrßzky budou slou₧it jako podklad pro naÜe menu. Pro v²b∞r jednotlivΘ polo₧ky nßm poslou₧φ kurzor, takΘ namalovan²:

Cursor.png
Kurzor, obrßzek PNG 9 x 15 pixel∙.

Dßle bude pod kurzorem zobrazen jeÜt∞ popis vybranΘ funkce. To provedeme pomocφ textovΘ polo₧ky, vykreslenΘ metodou drawString.

Krom∞ pohybu kurzoru, kter² budeme p°i stisku klßvesy provßd∞t, budeme takΘ kontrolovat zvolenou polo₧ku nabφdky. Tak budeme moci sprßvn∞ vyhodnotit volbu a zavolat vybranou metodu. Pro vyhodnocenφ stisknut²ch tlaΦφtek jsem pou₧il metodu keyPressed t°φdy Canvas, kterß vracφ k≤d stisknutΘ klßvesy. Krom∞ toho umφ i vyhodnotit tzv. GAME ACTION k≤dy klßves. Jsou to k≤dy urΦenΘ pro klßvesy, u kter²ch v²robce p°edpoklßdal, ₧e budou primßrn∞ pou₧φvßny k ovlßdßnφ her. Bohu₧el rozdφlnß implementace Javy od r∙zn²ch v²robc∙ v tomto spφÜe ud∞lala zmatek a jß jsem rad∞ji pou₧il ovlßdßnφ Φφseln²mi klßvesami: 1 - doleva, 3 - doprava a 2 - v²b∞r polo₧ky.

...a pak n∞jak² ten program

Pou₧ijeme op∞t t°φdu Abc.java. V tomto p°φkladu bude postrßdat p°φkazy pro tvorbu menu, to nynφ bude zßle₧itost t°φdy Menu.java. T°φda Abc.java obsahuje nßsledujφcφ k≤d:


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

public class Abc extends MIDlet implements CommandListener {

  Display disp;
  Command cmd_menu;
  Canvas can;
  List lst_nast;
  String str_about;
  Form frm_about;
  boolean barva;

  public Abc() {

    cmd_menu = new Command("Menu", Command.SCREEN, 1);

    lst_nast = new List("Nastaveni", Choice.MULTIPLE);
    lst_nast.append("Zvuk", null);
    lst_nast.append("Vibrace", null);

    str_about = "Prvnφ MIDlet, verze 1.0, p°φklad ze serveru interval.cz";

    frm_about = new Form("Info");
    frm_about.append(str_about);
  }

  public void startApp() {
    menu();
  }

  public void pauseApp() { }

  public void destroyApp(boolean unconditional) {
    notifyDestroyed();
  }

  public void commandAction(Command c, Displayable d) {

      if(c == cmd_menu) { menu(); }
  }

  public void info() {

      disp = Display.getDisplay(this);
      frm_about.addCommand(cmd_menu);
      frm_about.setCommandListener(this);
      disp.setCurrent(frm_about);
  }

  public void nast() {

      disp = Display.getDisplay(this);
      lst_nast.addCommand(cmd_menu);
      lst_nast.setCommandListener(this);
      disp.setCurrent(lst_nast);
  }

  public void menu() {
      disp = Display.getDisplay(this);
      barva = disp.isColor();
      can = new Menu(this);
      disp.setCurrent(can);
  }
}

Jak sami vidφte neobsahuje nic zvlßÜtnφho. Jedinß v∞c, kterß je zde novß, je metoda isColor, kterß vracφ true v p°φpad∞ barevnΘho displeje nebo false v p°φpad∞ displeje ΦernobφlΘho. To, o Φem je dneÜnφ Φlßnek, je celΘ v t°φd∞ Menu.java. Obsahuje veÜkerΘ vykreslovßnφ, zm∞nu vybran²ch polo₧ek a p°φkazy pro provedenφ vybranΘ akce.


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

public class Menu extends Canvas {

  Abc midlet;
  Image img_menu;
  Image img_cursor;
  int osa_x = 12;
  int vyber = 1; // index vybrane polozky
  String label;
  String str_menu;

  public Menu(Abc midlet) {
    this.midlet = midlet; // v konstruktoru pouzijeme odkaz na tridu Abc.java
    try {

    // podle typu displeje vybereme podklad
      if(midlet.barva) { str_menu = "/menu_c.png"; } else { str_menu = "/menu.png"; }
      img_menu = Image.createImage(str_menu);
      img_cursor = Image.createImage("/cursor.png"); // a vytvorime v pameti obrazek kurzoru
      } catch(Exception e) { }

  }

  public void paint(Graphics g) {

    g.setColor(255, 255, 255);
    g.fillRect(0, 0, getWidth(), getHeight()); // nejprve vybarvime plochu bile
    g.drawImage(img_menu, 0, 0, g.TOP|g.LEFT); // a pak umistime nejprve podklad
    g.drawImage(img_cursor, osa_x, 35, g.TOP|g.LEFT); // nasledovany kruzorem, osa_x urcuje pozici
    switch(vyber) { // podle vybrane polozky zobrazime komentar
      case(1): label = "Konec"; break;
      case(2): label = "Nastaveni"; break;
      case(3): label = "Info"; break;
    }
    if(midlet.barva) { g.setColor(0, 0, 255); } else { g.setColor(0, 0, 0); }
    g.drawString(label, 35, 50, g.TOP|g.LEFT);

  }

  protected void keyPressed(int keyCode) { // udalost vyvolana pri stisku tlacitka
    switch(keyCode) {
      case(49): left(); break; // stisknuta klavesa 1 - kurzor doleva
      case(51): right(); break; // klavesa 3 - kurzor doprava
      case(50): proceed(); break; // klavesa 2 - vyber polozky
    }
  }

  public void left() {
      if(osa_x > 12) {
          osa_x = osa_x - 34;
          vyber = vyber - 1;
          repaint(); // vykresli podklad a kurzor na nove pozici
      } else {
          osa_x = 80;
          vyber = 3;
          repaint();
      }
  }

  public void right() {
      if(osa_x < 80) {
          osa_x = osa_x + 34;
          vyber = vyber + 1;
          repaint();
      } else {
          osa_x = 12;
          vyber = 1;
          repaint();
      }
  }

  public void proceed() {
    switch(vyber) { // zjistime vybranou akci a zavolame metodu
        case(1): midlet.destroyApp(true); break;
        case(2): midlet.nast(); break;
        case(3): midlet.info(); break;
    }
  }

}

Jak to vlastn∞ pracuje?

Po spuÜt∞nφ vytvo°φ midlet instanci t°φdy Menu.java, kterou umφstφ na displej. Tato t°φda vykreslφ na displej podklad menu, kurzor a popisek prßv∞ zvolenΘ polo₧ky z nabφdky. Dßle zajiÜ¥uje "hlφdßnφ" stisknut²ch tlaΦφtek. P°i stisknutφ tlaΦφtka 1 nebo 3 zavolß metodu left() nebo right() pro pohyb kurzoru. Tyto metody d∞lajφ nßsledujφcφ: zkontrolujφ, zda u₧ kurzor nenφ na kraji menu a podle toho zm∞nφ jeho sou°adnice, potΘ zm∞nφ index zvolenΘ polo₧ky a zavolajφ metodu repaint(), kterß se postarß o p°ekreslenφ displeje. P°i stisknutφ tlaΦφtka 2 je zavolßna metoda proceed(). Ta zjistφ, kterß polo₧ka menu je vybranß, a podle toho zavolß metodu t°φdy Abc.java. Jak sami vidφte, nenφ to p°φliÜ slo₧itΘ, jedinΘ, na co je t°eba dßvat pozor, je velikost displej∙ a volba pou₧it²ch klßvesov²ch k≤d∙. Pak u₧ je jen na programßtorovi, pro jakou metodu tvorby menu se p°i psanφ midletu rozhodne.

V p°φkladu jsem pou₧il podklad pro menu, kter² je vyhovujφcφ pro v∞tÜinu dnes vyrßb∞n²ch mobilnφch telefon∙. Nßsledujφcφ obrßzky ukazujφ, jak menu vypadß na r∙zn²ch mobilnφch telefonech:

Nokia 7210
Nokia 7210
Siemens S55
Siemens S55
Siemens SL45i
Siemens SL45i
Siemens M50
Siemens M50
Motorola i85s
Motorola i85s

V Φlßnku popsan² postup je jen malou ukßzkou, kudy lze p°i tvorb∞ menu jφt, mo₧nostφ je ale mnohem vφc. Zßle₧φ jen na tvo°ivosti autora aplikace, jak si s tφm poradφ a kolik prßce si s tvorbou menu dß. Nejvφce mo₧nostφ nabφzejφ samoz°ejm∞ barevnΘ displeje, kter²ch je v nov²ch mobilnφch telefonech Φφm dßl vφc, co₧ v²vojß°i jen uvφtajφ. Otevφrajφ se tφm dalÜφ mo₧nosti jak p°iblφ₧it kvalitu mobilnφch aplikacφ jejich "plnokrevn²m" alternativßm, kterΘ znßme z PC.



Petr Kova°φk (28.3. 2003)

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.