Interval.cz
J2ME v p°φkladech - vybφrßme si

╚asto pot°ebujeme nabφdnout u₧ivateli, aby si vybral jednu z n∞kolika mo₧nostφ a tφm urΦil dalÜφ chod aplikace. Nebo mu nabφdneme mo₧nost v²b∞ru n∞kolika polo₧ek najednou a kombinaci nechßme na n∞m. Znßme to z mnoha aplikacφ a ani aplikace pro mobilnφ telefony nejsou v tomto sm∞ru v²jimkou. A prßv∞ v tomto Φlßnku se nauΦφme pracovat s komponentami pro v²b∞r polo₧ek ze seznamu, ukß₧eme si, jak se tvo°φ a jak je kombinovat.

T°φdy List a ChoiceGroup

T°φdy List a ChoiceGroup majφ na prvnφ pohled mnoho spoleΦnΘho, ale p°esto jsou odliÜnΘ. T°φda List je potomkem t°φdy Screen, zatφmco ChoiceGroup je potomek t°φdy Item. V praxi to znamenß, ₧e List m∙₧eme umφstit na displej samostatn∞, naproti tomu skupinu prvk∙ ChoiceGroup musφme umφstit na formulß°. M∙₧e to vypadat jako zbyteΦnost, ale mß to svoje opodstatn∞nφ, v nßsledujφcφch p°φkladech si ukß₧eme d∙vod.

T°φda List implementuje rozhranφ Choice, kterΘ nabφzφ t°i typy seznamu: EXCLUSIVE, MULTIPLE a IMPLICIT. Zde je p°ehled jejich vlastnostφ:

  • Choice.EXCLUSIVE - z nabφdky je mo₧no vybrat jen jeden prvek.
  • Choice.MULTIPLE - m∙₧eme vybrat ₧ßdn², jeden nebo vφce prvk∙ z nabφdky.
  • Choice.IMPLICIT - polo₧ka z nabφdky je vybrßna v okam₧iku, kdy je oznaΦena kurzorem.

Nejprve si vytvo°φme jednoduch² seznam typu EXCLUSIVE. Tento typ seznamu umo₧≥uje u₧ivateli v²b∞r jen jednΘ ze zobrazen²ch mo₧nostφ. Ukßzkovß aplikace bude simulovat objednßvkov² systΘm na osobnφ automobily. Nejprve mu dßme na v²b∞r z n∞kolika barevn²ch provedenφ. Zde je zdrojov² k≤d prvnφho p°φkladu:

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

public class Abc extends MIDlet implements CommandListener {

  List lst_barva;

  Display disp;

  Command cmd_exit;
  Command cmd_next;

  Form frm_barva;

  StringItem si_barva;

  public Abc() {

    cmd_next = new Command("Dalsi", Command.SCREEN, 1);
    cmd_exit = new Command("Konec", Command.SCREEN, 1);

    /** Zde si vytvo°φme instanci t°φdy LIST kterß bude obsahovat p°edem definovan²
    * seznam polo₧ek, atribut EXCLUSIVE °φkß ₧e je mo₧no vybrat jen jednu z polo₧ek.
    */

    lst_barva = new List("Barva", Choice.EXCLUSIVE);
    lst_barva.append("Cervena", null);
    lst_barva.append("Modra", null);
    lst_barva.append("Zelena", null);
    lst_barva.append("Bila", null);
    lst_barva.append("Cerna", null);
    lst_barva.addCommand(cmd_next);
    lst_barva.addCommand(cmd_exit);

    si_barva = new StringItem("Vybrali jsme", "");

    frm_barva = new Form("Barva");
    frm_barva.addCommand(cmd_exit);
    frm_barva.append(si_barva);

  }

  public void startApp() {

    disp = Display.getDisplay(this);
    lst_barva.setCommandListener(this);
    disp.setCurrent(lst_barva);
  }

  public void pauseApp() { }

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

  public void commandAction(Command c, Displayable d) {
    if(c == cmd_exit) { notifyDestroyed(); }
    if(c == cmd_next) { proceed(); }
  }

  public void proceed() {

    /** metodou getSelectedIndex zjistφme vybranou polo₧ku, ty jsou v seznamu indexovßny
    * od nuly tak₧e prvnφ polo₧ka je 0, druhß je 1 atd. */

    int select = lst_barva.getSelectedIndex();

    si_barva.setText(lst_barva.getString(select));

    frm_barva.setCommandListener(this);
    disp.setCurrent(frm_barva);

  }
}

Tento mal² midlet zobrazφ nabφdku barev a umo₧nφ u₧ivateli v²b∞r jen jednΘ z nich. Po v²b∞ru barvy toto u₧ivatel potvrdφ p°φkazem DalÜφ. Jak je vid∞t na nßsledujφcφch obrßzcφch, je zobrazenφ t°φdy List pln∞ zßvislΘ na implementaci Javy v mobilnφm telefonu. Jak u₧ tedy sprßvn∞ tuÜφte, je to vysoko·rov≥ovß komponenta.

Nokia 7210, t°φda LIST
List na mobilnφm telefonu Nokia 7210...
Motorola 720i, t°φda LIST
...na mobilnφm telefonu Motorola T720i...
Siemens C55 a t°φda LIST
...na Siemensu C55...
Sony Ericsson P800 - t°φda LIST
...a nakonec na SE P800.

Toto byl jednoduch² p°φklad jak nabφdnou u₧ivateli v²b∞r jednΘ polo₧ky ze seznamu. UrΦit∞ se te∩ ptßte, jak to ud∞lat, kdy₧ chceme dßt u₧ivateli na v²b∞r vφc ne₧ jen jednu mo₧nost z celΘ nabφdky? Ani to nenφ problΘm. StaΦφ pßr ·prav a aplikace toto umo₧nφ k naÜφ plnΘ spokojenosti. Pou₧ijeme seznam typu MULTIPLE, ve kterΘm je mo₧nΘ vybrat libovoln² poΦet polo₧ek.

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

public class Abc extends MIDlet implements CommandListener {

  List lst_vybava;

  Display disp;

  Command cmd_exit;
  Command cmd_next;

  Form frm_vybava;

  StringItem si_vybava;

  public Abc() {

    cmd_next = new Command("Dalsi", Command.SCREEN, 1);
    cmd_exit = new Command("Konec", Command.SCREEN, 1);

    /** Zde si op∞t vytvo°φme instanci t°φdy LIST kterß bude obsahovat p°edem definovan²
    * seznam polo₧ek, atribut MULTIPLE °φkß ₧e je mo₧no vybrat libovoln² poΦet polo₧ek.
    */

    lst_vybava = new List("Vybava", Choice.MULTIPLE);
    lst_vybava.append("Klimatizace", null);
    lst_vybava.append("Airbag", null);
    lst_vybava.append("Autoradio", null);
    lst_vybava.append("El. okna", null);
    lst_vybava.addCommand(cmd_next);
    lst_vybava.addCommand(cmd_exit);

    si_vybava = new StringItem("Zvolena vybava", "");

    frm_vybava = new Form("Vybava");
    frm_vybava.addCommand(cmd_exit);
    frm_vybava.append(si_vybava);

  }

  public void startApp() {

    disp = Display.getDisplay(this);
    lst_vybava.setCommandListener(this);
    disp.setCurrent(lst_vybava);
  }

  public void pauseApp() { }

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

  public void commandAction(Command c, Displayable d) {
    if(c == cmd_exit) { notifyDestroyed(); }
    if(c == cmd_next) { proceed(); }
  }

  public void proceed() {

    /** nejprve si projdeme vÜechny prvky seznamu, jeho velikost zjistφme
    * metodou size(); */

    int prvky = lst_vybava.size();
    String str_vybava = "\n";

    /** m∙₧eme samoz°ejm∞ pou₧φt i cyklus typu for(int a=0; a<lst_vybava.size(); a++)
    * ale je dobrΘ si uv∞domit ₧e pak se zjiÜ¥uje velikost seznamu p°i ka₧dΘm pr∙b∞hu
    * cyklu co₧ zpomaluje aplikaci */

    for(int a=0; a<prvky; a++) {
      if(lst_vybava.isSelected(a)) {
        // pokud je prvek vybran² p°idß se jeho popis k seznamu
        str_vybava = str_vybava + lst_vybava.getString(a) + "\n";
     }
   }

    si_vybava.setText(str_vybava);
    frm_vybava.addCommand(cmd_exit);
    frm_vybava.setCommandListener(this);
    disp.setCurrent(frm_vybava);


  }
}

Tento jednoduch² midlet nabφdne u₧ivateli n∞kolik mo₧nostφ vybavenφ automobilu a umo₧nφ mu vybrat libovoln² poΦet polo₧ek. Po volb∞ DalÜφ zobrazφ seznam vybran²ch polo₧ek jako text, jednotlivΘ polo₧ky jsou na odd∞len²ch °ßdcφch. Jak to vypadß na mobilnφch telefonech, m∙₧ete vid∞t na nßsledujφcφch obrßzcφch:

Nokia 6310i nabφdka polo₧ek
Menu na telefonu Nokia 6310i...
Nokia 6310i, seznam vybran²ch
...a seznam vybran²ch polo₧ek.
Siemens SL45i v²b∞r
Zde je seznam na telefonu Siemens SL45i...
Siemens SL45i seznam vybran²ch polo₧ek
...a zde je v²pis vybran²ch polo₧ek.

Co ale v p°φpad∞, kdy chcete, aby n∞kterΘ polo₧ky byly vybrßny u₧ v okam₧iku zobrazenφ nabφdky a u₧ivatel je mohl jen odebrat? Op∞t existuje jednoduchΘ °eÜenφ, staΦφ pou₧φt metodu setSelectedIndex(int index, boolean selected). Vlo₧te nßsledujφcφ k≤d do p°edchozφho p°φkladu na mφsto konstruktoru seznamu a aplikaci spus¥te. Polo₧ka "Klimatizace" a "Autoradio" budou vybrßny u₧ v okam₧iku zobrazenφ seznamu. OznaΦenΘ polo₧ky majφ indexy 0 a 2, co₧ napovφdß, ₧e polo₧ky seznamu jsou indexovßny od nuly.

lst_vybava = new List("Vybava", Choice.MULTIPLE);
lst_vybava.append("Klimatizace", null);
lst_vybava.append("Airbag", null);
lst_vybava.append("Autoradio", null);
lst_vybava.append("El. okna", null);
lst_vybava.setSelectedIndex(0, true);
lst_vybava.setSelectedIndex(2, true);
lst_vybava.addCommand(cmd_next);
lst_vybava.addCommand(cmd_exit);

To byl popis seznam∙ typu EXCLUSIVE a MULTIPLE. Zb²vß nßm tedy seznam typu IMPLICIT. Tento typ seznamu mß n∞kterΘ odliÜnosti, kterΘ jej stavφ trochu mimo p°edchozφ typy.

Prvnφ odliÜnost spoΦφvß ve v²b∞ru polo₧ky. Zatφmco dosud byla polo₧ka vybrßna a₧ tehdy, kdy₧ ji u₧ivatel "zaÜkrtnul", v seznamu typu IMPLICIT je vybrßna v okam₧iku, kdy je na nφ umφst∞n kurzor. Odpadajφ tedy zaÜkrtßvßtka, checkboxy a podobnΘ grafickΘ prvky, zobrazujφcφ aktußlnφ v²b∞r. Ten je prezentovßn kurzorem, kter²m se po seznamu pohybujeme.

DalÜφ rozdφl je v pou₧itφ rozhranφ CommandListener. Pokud pou₧φvßme seznam IMPLICIT, m∙₧eme pou₧φt p°φkaz SELECT_COMMAND, kter² je zavolßn v okam₧iku, kdy chceme "oznaΦit" polo₧ku. Ukß₧eme si v nßsledujφcφm p°φkladu, jak to funguje. Nejprve vytvo°φme seznam typu IMPLICIT a takΘ odstranφme tlaΦφtko pro pokraΦovßnφ, tato metoda bude spuÜt∞na v²b∞rem polo₧ky a pou₧itφm p°φkazu SELECT_COMMAND:

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

public class Abc extends MIDlet implements CommandListener {

  List lst_barva;

  Display disp;

  Command cmd_exit;

  Form frm_barva;

  StringItem si_barva;

  public Abc() {

    cmd_exit = new Command("Konec", Command.SCREEN, 1);

    /** Zde si vytvo°φme instanci t°φdy LIST kterß bude obsahovat p°edem definovan²
    * seznam polo₧ek, atribut IMPLICIT urΦuje typ seznamu.
    */

    lst_barva = new List("Barva", Choice.IMPLICIT);
    lst_barva.append("Cervena", null);
    lst_barva.append("Modra", null);
    lst_barva.append("Zelena", null);
    lst_barva.append("Bila", null);
    lst_barva.append("Cerna", null);
    lst_barva.addCommand(cmd_exit);

    si_barva = new StringItem("Vybrali jsme", "");

    frm_barva = new Form("Barva");
    frm_barva.addCommand(cmd_exit);
    frm_barva.append(si_barva);

  }

  public void startApp() {

    disp = Display.getDisplay(this);
    lst_barva.setCommandListener(this);
    disp.setCurrent(lst_barva);
  }

  public void pauseApp() { }

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

  public void commandAction(Command c, Displayable d) {
    if(c == cmd_exit) { notifyDestroyed(); }
    // pouzijeme prikaz SELECT_COMMAND ktery je k dispozici v seznamu typu IMPLICIT
    if(c == List.SELECT_COMMAND) { proceed(); }
  }

  public void proceed() {

    /** metodou getSelectedIndex zjistφme vybranou polo₧ku, ty jsou v seznamu indexovßny  
    * od nuly tak₧e prvnφ polo₧ka je 0, druhß je 1 atd. */

    int select = lst_barva.getSelectedIndex();

    si_barva.setText(lst_barva.getString(select));

    frm_barva.setCommandListener(this);
    disp.setCurrent(frm_barva);

  }
}

P°i b∞hu midletu nejlΘpe sami poznßte rozdφl v pou₧itφ seznamu typu IMPLICIT. Jeho vyu₧itφ je velmi jednoduchΘ, p°φjemnΘ a praktickΘ. S jeho pomocφ se dajφ velmi elegantn∞ tvo°it nabφdky funkcφ aplikace nebo seznamy polo₧ek, kterΘ se po v²b∞ru zobrazφ detailn∞ji. V p°φÜtφm Φlßnku si vysv∞tlφme, jak pracuje velmi podobnß komponenta pro v²b∞r prvk∙ ChoiceGroup.



Petr Kova°φk (24.4. 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∙.