



<html>
<head>
  <title>javabog.dk -  - Mobiltelefoner (J2ME)</title>
  <link rev="stylesheet" type="text/css" href="../typografi.css">
  <meta name="description" content="Lærebog i Java. Af Jacob Nordfalk. Udkommet hos Forlaget Globe">
  <meta name="keywords" content="designmønster, programmering, OOP, objekter, klasser, objektorienteret programmering, Java, JSP, lærebog, UML, IT">
</head>
<body bgcolor="#ffffff">



<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel12.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel14.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>

<H1 CLASS="western" STYLE="">13 <a name='afsn13'></a>Mobiltelefoner
(J2ME)</H1>
<DIV ID="Indholdsfortegnelse19">
  <P STYLE="margin-top: 0.3cm; margin-bottom: 0cm"><BR>
  </P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.1
  Introduktion til midletter  182</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.1.1
  Eksempel - en simpel midlet  182</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.1.2
  Pr&oslash;vek&oslash;re en midlet  182</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.1.3
  Midletters livscyklus  183</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.2
  Brugergr&aelig;nseflader i midletter  184</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.2.1
  Klassen Display (den fysiske sk&aelig;rm)  184</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.2.2
  Klassen Displayable (sk&aelig;rmbilleder)  185</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.2.3
  Klassen Ticker (rulletekst p&aring; et sk&aelig;rmbillede)  185</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.2.4
  Klassen Image (billeder)  185</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.2.5
  Klassen Font (skrifttyper)  186</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.3
  Direkte grafiktegning og spil  187</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.3.1
  Klassen Canvas  188</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.3.2
  Klassen GameCanvas og lagdelt grafik  188</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.3.3
  Klassen Graphics  189</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.4
  Grafiske standardkomponenter  190</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.1
  Eksempel: G&aelig;t et tal  190</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.2
  Kommandoer og h&aelig;ndelser i midletter  191</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.3
  TextBox  192</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.4
  Alert  192</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.5
  List  193</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.4.6
  Form  194</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.5
  Tilg&aelig;ngelige klasser fra J2SE  195</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.5.1
  Pakken java.lang  195</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.5.2
  Pakken java.util  195</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.5.3
  Pakken java.io  195</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.6
  Netv&aelig;rkskommunikation  196</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.6.1
  Pakken javax.microedition.io  196</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.6.2
  Eksempel: Kommunikation med webserver  197</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.7
  Gemme data i telefonen  199</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.8
  Udviklingsv&aelig;rkt&oslash;jer til midletter  200</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.8.1
  Wireless Toolkit  200</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.8.2
  Sun ONE Studio Mobile Edition  200</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.8.3
  Borland JBuilder MobileSet  201</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.9
  Opbygningen af J2ME  202</B></FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.9.1
  Konfigurationer  202</FONT></FONT></P>
  <P STYLE="margin-left: 0.6cm; margin-top: 0.08cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 9pt">13.9.2
  Profiler  203</FONT></FONT></P>
  <P STYLE="margin-left: 0.3cm; margin-top: 0.15cm; margin-bottom: 0cm">
  <FONT FACE="Helvetica, sans-serif"><FONT SIZE=2 STYLE="font-size: 11pt"><B>13.10
  Yderligere l&aelig;sning  203</B></FONT></FONT></P>
</DIV>
<P CLASS="western">J2ME (Java 2 Micro Edition) er Suns
Java-udviklingsplatform til at lave applikationer, der er beregnet
til apparater med begr&aelig;nset hukommelse. 
</P>
<P CLASS="western">Det er muligt at sammens&aelig;tte bestanddelene i
J2ME, s&aring;dan at man f&aring;r de klasser, der er brug for til en
bestemt kategori af apparater.</P>
<P CLASS="western">Der, hvor J2ME har vundet st&oslash;rst
udbredelse, er inden for udviklingen af sm&aring; programmer beregnet
til mobiltelefoner (kaldet midletter), og det er det, vi vil
besk&aelig;ftige os med her. Andre anvendelsesmuligheder beskrives
kort i <a href='kapitel13.jsp#afsn13.9'>afsnit 13.9</a>.</P>
<P CLASS="western">For kortheds skyld vil vi benytte ben&aelig;vnelsen
'telefon' i det f&oslash;lgende, og det er op til l&aelig;seren selv
at l&aelig;se 'telefon' som 'mobiltelefoner og en lang r&aelig;kke
andre sm&aring; h&aring;ndholdte computere og apparater'.</P>
<H2 CLASS="western">13.1 <a name='afsn13.1'></a>Introduktion til midletter</SPAN></H2>
<P CLASS="western">Midletter er sm&aring; programmer, som er beregnet
til at k&oslash;re p&aring; en mobiltelefon. Ordet 'midlet' kommer
fra MIDP (Mobile Information Device Profile) og skal opfattes analogt
med ordet 'applet'. Ligesom appletter skal arve fra klassen Applet,
skal midletter arve fra klassen  MIDlet (der ligger i pakken
javax.microedition.midlet).</P>
<H3 CLASS="western">13.1.1 <a name='afsn13.1.1'></a>Eksempel - en simpel midlet</H3>
<P CLASS="western">L<IMG SRC="bog14_html_m33dfaf2c.png" NAME="Grafik40" ALIGN=RIGHT HSPACE=4 BORDER=0>ad
os se n&aelig;rmere p&aring;, hvad man skal g&oslash;re, hvis man vil
skrive sine egne midletter. Nedenfor er et simpelt eksempel p&aring;
en midlet, der viser en (fiktiv) vejrudsigt:</P>
<PRE CLASS="kode-western">import javax.microedition.midlet.*;
<SPAN LANG="da-DK">import javax.microedition.lcdui.*;</SPAN>

<SPAN LANG="da-DK">public class Vejrmidlet extends MIDlet</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK"><I>   // systemet starter midletten</I></SPAN>
<SPAN LANG="da-DK">  public void startApp()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK"><I>    // opret et sk&aelig;rmbillede (en liste)</I></SPAN>
<SPAN LANG="da-DK">    List sb = new List(&quot;Vejret&quot;, List.IMPLICIT);</SPAN>
<SPAN LANG="da-DK">    sb.append(&quot;Det bliver let skyet og bl&aelig;sende&quot;, null);</SPAN>
<SPAN LANG="da-DK">    sb.append(&quot;Temperatur mellem 17 og 22 grader&quot;, null);</SPAN>

<SPAN LANG="da-DK"><I>    // vis sk&aelig;rmbilledet</I></SPAN>
<SPAN LANG="da-DK">    Display.getDisplay(this).setCurrent( sb );</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK"><I>   // systemet standser midletten</I></SPAN>
<SPAN LANG="da-DK">  public void pauseApp() {}</SPAN>

<SPAN LANG="da-DK"><I>   // systemet smider midletten v&aelig;k</I></SPAN>
<SPAN LANG="da-DK">  public void destroyApp(boolean unconditional) {}</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
I dette eksempel bruger vi en List (en valgliste) og tilf&oslash;jer
den tekst vi &oslash;nsker skal vises ud for hvert af listens
elementer.</P>
<P CLASS="western">N&aring;r startApp() kaldes af systemet skal
midletten bestemme, hvad der vises p&aring; sk&aelig;rmen. Det g&oslash;res
med</P>
<PRE CLASS="kode-western">  Display.getDisplay(this).setCurrent( sk&aelig;rmbillede )</PRE><P CLASS="western">
hvor 'sk&aelig;rmbillede' kan v&aelig;re f.eks. en List, TextBox,
Form eller Canvas (se senere). 
</P>

<H3 CLASS="western">13.1.2 <a name='afsn13.1.2'></a>Pr&oslash;vek&oslash;re en midlet</H3>
<P CLASS="western"><SPAN LANG="da-DK">F&oslash;r du kan overs&aelig;tte
og k&oslash;re en midlet skal du have fat i et udviklingsv&aelig;rkt&oslash;j
til mobiltelefonudvikling. Udvilkingsv&aelig;rkt&oslash;jer til J2ME
behandles i <a href='kapitel13.jsp#afsn13.8'>afsnit 13.8</a>.</SPAN></P>
<P CLASS="western">Under udviklingen af en midlet vil man normalt
ogs&aring; pr&oslash;ve at k&oslash;re den, f&oslash;r man overf&oslash;rer
programmet til en rigtig telefon. Til dette form&aring;l har de
fleste udvilkingsv&aelig;rkt&oslash;jer en emulator indbygget, der
kan udf&oslash;re midletten, som om den k&oslash;rte p&aring; en
rigtig telefon. Figuren til h&oslash;jre for programudskriften
ovenfor viser en s&aring;dan emulator (kaldet DefaultColorPhone).</P>
<P CLASS="western">Hvis ens program best&aring;r af flere klasser, er
det n&oslash;dvendigt at pakke dem i en JAR-fil, for at de kan hentes
ned af brugeren. Derudover skal man lave en manifestfil, der
indeholder information om indholdet i JAR-filen. Man kan oprette
disse filer med de fleste udviklingsv&aelig;rkt&oslash;j til
midletter.</P>
<H3 CLASS="western">13.1.3 <a name='afsn13.1.3'></a>Midletters livscyklus</H3>
<P CLASS="western">En midlets livscyklus styres af et program i
mobiltelefonen, der hedder Application Management Software (AMS). 
</P>
<P CLASS="western">N&aring;r brugeren &oslash;nsker at k&oslash;re en
midlet, henter AMS midletten ned fra en server og starter midletten:</P>
<UL>
  <LI><P CLASS="western">F&oslash;rst kaldes midlettens <B>konstrukt&oslash;r</B>.
  Mens konstrukt&oslash;ren udf&oslash;res, er midletten standset, og
  den kan ikke modtage brugerinput eller vise noget p&aring; sk&aelig;rmen.</P>
  <LI><P CLASS="western">N&aring;r konstrukt&oslash;ren er f&aelig;rdig
  med at blive udf&oslash;rt, kalder AMS metoden <B>startApp()</B>,
  hvorved midletten g&oslash;res aktiv og venter p&aring; input fra
  brugeren (eller fra en server). 
  </P>
  <LI><P CLASS="western">AMS kan kalde <B>pauseApp()</B> for at
  standse midlettens programudf&oslash;rsel og give kontrollen til et
  andet program, for eksempel et telefonopkald. <BR>Senere,  n&aring;r
  det andet program er afsluttet, genoptager AMS midlettens
  programudf&oslash;relse ved at kalde startApp() igen.</P>
  <LI><P CLASS="western">N&aring;r AMS vil frigive hukommelsen til et
  andet program, kalder den <B>destroyApp()</B> og smider midletten
  v&aelig;k.</P>
</UL>
<P CLASS="western">Metoderne startApp(), pauseApp() og destroyApp()
er abstrakte og skal derfor altid implementeres. 
</P>
<P CLASS="western">Kode, der skal udf&oslash;res ved initialiseringen
af midletten, b&oslash;r egentlig v&aelig;re i midlettens konstrukt&oslash;r
fremfor i startApp(). 
</P>
<P CLASS="western">I pauseApp() kan man placere kode til at gemme
data indtil startApp() kaldes igen.</P>
<H2 CLASS="western" STYLE="">13.2 <a name='afsn13.2'></a>Brugergr&aelig;nseflader
i midletter</SPAN></H2>
<P CLASS="western">De muligheder, man har for at lave
brugergr&aelig;nseflader til en midlet, er defineret i pakken
javax.microedition.lcdui. 
</P>
<P CLASS="western">Det centrale element, n&aring;r man skal designe
brugergr&aelig;nseflader, er et sk&aelig;rmbillede (en klasse, der
arver fra Displayable). Et  sk&aelig;rmbillede er et objekt, som
viser grafik og tager imod indtastninger fra brugeren. Der kan kun
v&aelig;re &eacute;t sk&aelig;rmbillede synligt ad gangen.</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog14_html_1b94d99d.gif" NAME="Grafik7" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Klassen Canvas er beregnet til at lave direkte
grafiktegning (til f.eks. spil). Bruger man denne klasse, m&aring;
man selv tage h&oslash;jde for sk&aelig;rmst&oslash;rrelsen og
farvedybden. Denne klasse er n&aelig;rmere beskrevet i <a href='kapitel13.jsp#afsn13.3'>afsnit 13.3</a>,
Direkte grafiktegning og spil.</P>
<P CLASS="western"><SPAN LANG="da-DK">Der er 4 klasser til at lave
grafiske brugergr&aelig;nseflader v.hj.a. standardkomponenter, nemlig
Form, Alert, List og TextBox. N&aring;r man bruge disse klasser
beh&oslash;ver man ikke t&aelig;nke p&aring; hvilken sk&aelig;rmst&oslash;rrelse
og farvedybde telefonen har (de er programmeret til at ligne det
&oslash;vrige menusystem p&aring; den p&aring;g&aelig;ldende
telefon). Disse klasser er n&aelig;rmere beskrevet i <a href='kapitel13.jsp#afsn13.4'>afsnit 13.4</a> Grafiske standardkomponenter.</SPAN></P>

<H3 CLASS="western">13.2.1 <a name='afsn13.2.1'></a>Klassen Display (den fysiske sk&aelig;rm)</H3>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Display repr&aelig;senterer den fysiske sk&aelig;rm og har bl.a.
metoderne:</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">static Display
getDisplay(midlet)        skaffer Display-objektet</P>
<P CLASS="klasseoversigt---kompakt-western">boolean isColor()            om
telefonen har farvesk&aelig;rm</P>
<P CLASS="klasseoversigt---kompakt-western">int
numColors()            giver antallet af farver eller gr&aring;toner p&aring;
telefonen</P>
<P CLASS="klasseoversigt---kompakt-western">void
setCurrent(Displayable sk&aelig;rmbillede)   beder telefonen vise et
bestemt sk&aelig;rmbillede</P>
<P CLASS="klasseoversigt---kompakt-western">Displayable
getCurrent()          giver det aktuelle sk&aelig;rmbillede, der vises 
</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
flashBacklight(int varighed)      blinker med telefonens
baggrundsbelysning</P>
<P CLASS="klasseoversigt---kompakt-western">boolean vibrate(int
varighed)        vibrerer med telefonen</P>
<P CLASS="western">Midletten kan skifte mellem de forskellige
sk&aelig;rmbilleder ved at kalde metoden setCurrent(Displayable) p&aring;
Display-objektet. 
</P>
<P CLASS="western">Klassen Display er implementeret som en singleton,
s&aring; der kan kun v&aelig;re et sk&aelig;rmbillede synligt ad
gangen. Man f&aring;r fat i Display-objektet ved at kalde
Display.getDisplay() med midletten som parameter.</P>
<H3 CLASS="western">13.2.2 <a name='afsn13.2.2'></a>Klassen Displayable (sk&aelig;rmbilleder)</H3>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Displayable - metoder f&aelig;lles for alle sk&aelig;rmbilleder</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">String
getTitle()            giver titlen p&aring; sk&aelig;rmbilledet</P>
<P CLASS="klasseoversigt---kompakt-western">void setTitle(String
titel)          s&aelig;tter titlen</P>
<P CLASS="klasseoversigt---kompakt-western">Ticker
getTicker()            giver rulleteksten p&aring; sk&aelig;rmbilledet</P>
<P CLASS="klasseoversigt---kompakt-western">void setTicker(Ticker
rulletekst)        s&aelig;tter en rulletekst (i stedet for den gamle)</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
isShown()            tjekker, om sk&aelig;rmbilledet er synligt</P>
<P CLASS="klasseoversigt---kompakt-western">void addCommand(Command
k)        f&oslash;jer en kommando til sk&aelig;rmen</P>
<P CLASS="klasseoversigt---kompakt-western">void
removeCommand(Command k)      sletter en kommando fra sk&aelig;rmen</P>
<P CLASS="klasseoversigt---kompakt-western">void
setCommandListener(CommandListener l)  s&aelig;t lytter til kommandoer
for dette sk&aelig;rmbillede</P>
<P CLASS="klasseoversigt---kompakt-western">int getWidth()            giver
bredden af sk&aelig;rmbilledet</P>
<P CLASS="klasseoversigt---kompakt-western">int
getHeight()            giver h&oslash;jden af sk&aelig;rmbilledet 
</P>

<H3 CLASS="western">13.2.3 <a name='afsn13.2.3'></a>Klassen Ticker (rulletekst p&aring; et
sk&aelig;rmbillede)</H3>
<P CLASS="western">Man kan f&aring; en lille tekst til at rulle hen
over sk&aelig;rmen (en rulletekst - eng.: ticker). Det g&oslash;res
med f.eks.:</P>
<PRE CLASS="kode-western">Ticker rulletekst = new Ticker(&quot;Dette er en tekst der ruller hen over sk&aelig;rmen&quot;);
<SPAN LANG="da-DK">Displayable sk&aelig;rmbillede = new List(&quot;Vejret&quot;, List.IMPLICIT);</SPAN>
<SPAN LANG="da-DK">sk&aelig;rmbillede.setTicker( rulletekst );</SPAN></PRE><P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm">
<FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen Ticker (rulletekst p&aring;
et sk&aelig;rmbillede)</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">String
getString()            afl&aelig;ser rulleteksten</P>
<P CLASS="klasseoversigt---kompakt-western">void setString(String
str)          s&aelig;tter rulleteksten</P>

<H3 CLASS="western">13.2.4 <a name='afsn13.2.4'></a>Klassen Image (billeder)</H3>
<P CLASS="western">Et Image-objekt bruges til at tegne grafikbilleder
p&aring; sk&aelig;rmen (med Canvas) eller i forskellige grafiske
standardkomponenter s&aring;som Alert, Choice, Form og ImageItem.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Image</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(Image b)           opretter et billede ud fra det eksisterende
billede b</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(Image b, int x, y, br, h&oslash;, transf) ditto, men med
transformation og klipning</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(byte[] data, int afs, int lgd)  opretter billede fra array
af byte</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(String navnP&aring;Resurse)  opretter billede fra
navngiven resurse</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(InputStream)      opretter billede fra datastr&oslash;m</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createRGBImage(int[] rgb, int br, h&oslash;, boolean alfa) opretter
billede fra farvedata</P>
<P CLASS="klasseoversigt---kompakt-western">static Image
createImage(int bredde, int h&oslash;jde)   opretter et <B>foranderligt</B>
billede (der kan tegnes p&aring;)</P>
<P CLASS="klasseoversigt---kompakt-western">Graphics
getGraphics()            grafiktegning p&aring; et (foranderligt) billede</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
isMutable()              sand, hvis foranderligt, falsk, hvis uforanderligt</P>
<P CLASS="klasseoversigt---kompakt-western">int
getWidth()              giver bredden af billedet</P>
<P CLASS="klasseoversigt---kompakt-western">int
getHeight()              giver h&oslash;jden af billedet</P>
<P CLASS="klasseoversigt---kompakt-western">void getRGB(int[] rgb,
int afs, scLgd, x, y, br, h&oslash;)  afl&aelig;ser billeddata og
gemmer i arrayet rgb</P>
<P CLASS="western">Et billede er, afh&aelig;ngigt af hvordan det er
oprettet, enten uforanderligt (dvs. umuligt at &aelig;ndre i, n&aring;r
det f&oslash;rst er oprettet), eller foranderligt (dvs. der kan
&aelig;ndres i det, efter at det er blevet oprettet).</P>
<P CLASS="western">Uforanderlige billeder oprettes ved at kalde
createImage() med et array af byte, en datastr&oslash;m fra en fil
eller netv&aelig;rket.</P>
<P CLASS="western">Foranderlige (eng.: mutable) billeder kan man
&aelig;ndre i via et Graphics objekt. De oprettes ved at kalde
createImage() med en bredde og h&oslash;jde og starter med at v&aelig;re
helt hvide.</P>
<P CLASS="western">Bruges et foranderligt billede i grafiske
standardkomponenter, s&aring;som Alert, Choice, Form og ImageItem,
vil der blive taget en kopi af billedet.</P>
<H3 CLASS="western">13.2.5 <a name='afsn13.2.5'></a>Klassen Font (skrifttyper)</H3>
<P CLASS="western">Man kan bede om en given skrifttype ved hj&aelig;lp
af metoden Font.getFont() og angive  skriftstil, st&oslash;rrelse og
type som parametre. Metoden vil returnere den skrifttype, som kommer
t&aelig;ttest p&aring; det &oslash;nskede, ud fra de muligheder den
givne telefon har.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Font</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">static Font
getDefaultFont()      giver systemets standardskrifttype</P>
<P CLASS="klasseoversigt---kompakt-western">static Font getFont(int
skriftnr)    giver standardskriften for enten:<BR>        static int
FONT_STATIC_TEXT eller FONT_INPUT_TEXT</P>
<P CLASS="klasseoversigt---kompakt-western">static Font getFont(int
type, int stil, int st&oslash;rrelse) giver skrifttype t&aelig;ttest
p&aring; de angivne parametre<BR>static int STYLE_PLAIN, STYLE_BOLD,
STYLE_ITALIC, STYLE_UNDERLINED  skriftstil<BR>static int SIZE_SMALL,
SIZE_MEDIUM, SIZE_LARGE                  skriftst&oslash;rrelse<BR>static int
FACE_SYSTEM, FACE_MONOSPACE, FACE_PROPORTIONAL       skrifttype</P>
<P CLASS="klasseoversigt---kompakt-western">int
getStyle()        returnerer skriftstilen (fed, kursiv, understreget)</P>
<P CLASS="klasseoversigt---kompakt-western">int getSize()        giver
skriftst&oslash;rrelsen</P>
<P CLASS="klasseoversigt---kompakt-western">int getFace()        giver
skrifttypen</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
isPlain()        giver sand, hvis skriftstilen er 'plain' (ikke fed,
kursiv, ...)</P>
<P CLASS="klasseoversigt---kompakt-western">boolean isBold()        giver
sand, hvis skriftstilen er sat til fed skrift</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
isItalic()        giver sand, hvis skriftstilen er sat til kursiv</P>
<P CLASS="klasseoversigt---kompakt-western">boolean
isUnderlined()      giver sand, hvis skriftstilen  er sat til
understreget</P>
<P CLASS="klasseoversigt---kompakt-western">int getHeight()        giver
standardh&oslash;jden af en tekstlinje</P>
<P CLASS="klasseoversigt---kompakt-western">int
getBaselinePosition()      giver afstand i punkter fra top af teksten
til grundlinjen</P>
<P CLASS="klasseoversigt---kompakt-western">int charWidth(char
tegn)      giver bredden af et tegn i sk&aelig;rmpunkter</P>
<P CLASS="klasseoversigt---kompakt-western">int charsWidth(char[],
int afs, int lgd)  giver bredden af et array af tegn</P>
<P CLASS="klasseoversigt---kompakt-western">int stringWidth(String
streng)    giver bredden af en streng</P>
<P CLASS="klasseoversigt---kompakt-western">int substringWidth(String
str, int afs, int lgd) giver bredden af en delstreng</P>

<H2 CLASS="western" STYLE="">13.3 <a name='afsn13.3'></a>Direkte
grafiktegning og spil</SPAN></H2>
<P CLASS="western">Hvis man vil lave sin egen grafik, skal man arve
fra klassen Canvas og definere dens paint()-metode. Canvas er ogs&aring;
beregnet til at lave spil og har metoder til at opfange brugerens
tastetryk og evt. brug af et pegeredskab.</P>
<P CLASS="western">Her er et eksempel, der tegner en tekst og en
firkant, der kan styres med piletasterne.</P>
<P CLASS="western">F&oslash;rst sk&aelig;rmbilledet, der viser
grafikken:</P>
<IMG SRC="bog14_html_mc015516.png" NAME="Grafik14" ALIGN=RIGHT HSPACE=4 VSPACE=4 BORDER=0>
<PRE CLASS="kode-western">import javax.microedition.lcdui.*;

<SPAN LANG="da-DK">public class Canvasgrafik extends Canvas</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private int x,y;</SPAN>

<SPAN LANG="da-DK">  public Canvasgrafik()</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    x = getWidth()/2;</SPAN>
<SPAN LANG="da-DK">    y = getHeight()/2;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">    </SPAN>
<SPAN LANG="da-DK">  public void paint(Graphics g)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK"><I>    // slet baggrunden</I></SPAN>
<SPAN LANG="da-DK">    g.setColor( 0x00ffffff ); <I>// hvid</I></SPAN>
<SPAN LANG="da-DK">    g.fillRect(0, 0, getWidth(), getHeight());</SPAN>

<SPAN LANG="da-DK">    g.setColor( 0x00000000 ); <I>// sort</I></SPAN>
<SPAN LANG="da-DK">    g.drawString(&quot;Brug piletasterne&quot;,0,0,</SPAN>
<SPAN LANG="da-DK">      Graphics.TOP|Graphics.LEFT);</SPAN>
<SPAN LANG="da-DK">    g.fillRect(x,y,3,3);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  protected void keyPressed(int tastkode)</SPAN>
<SPAN LANG="da-DK">  {</SPAN>
<SPAN LANG="da-DK">    switch (getGameAction(tastkode)) {</SPAN>
<SPAN LANG="da-DK">      case UP:   y--; break;</SPAN>
<SPAN LANG="da-DK">      case DOWN: y++; break;</SPAN>
<SPAN LANG="da-DK">      case LEFT: x--; break;</SPAN>
<SPAN LANG="da-DK">      case RIGHT:x++; break;</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    repaint();  <I>// bed systemet kalde paint</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><P CLASS="western">
Vi har defineret paint() for at kunne tegne noget p&aring; sk&aelig;rmen.
Graphics-objektet, der overf&oslash;res, minder meget om det
Graphics-objekt, man kender fra java.awt.</P>
<P CLASS="western">Vi har ogs&aring; defineret keyPressed() for at f&aring;
at vide, n&aring;r brugeren trykker p&aring; en tast. For at f&aring;
tastkoden omsat til en handling i 'spillet' p&aring; en
platformsuafh&aelig;ngig m&aring;de kalder vi getGameAction().</P>
<P CLASS="western">Her er midletten, der viser Canvas-objektet:</P>
<PRE CLASS="kode-western">import javax.microedition.midlet.*;
<SPAN LANG="da-DK">import javax.microedition.lcdui.*;</SPAN>

<SPAN LANG="da-DK">public class VisCanvasgrafik extends MIDlet</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">   Canvasgrafik grafik = new Canvasgrafik();</SPAN>

<SPAN LANG="da-DK">   public void startApp()</SPAN>
<SPAN LANG="da-DK">   {</SPAN>
<SPAN LANG="da-DK">      Display.getDisplay(this).setCurrent(grafik);</SPAN>
<SPAN LANG="da-DK">   }</SPAN>

<SPAN LANG="da-DK">   public void pauseApp() {}</SPAN>
<SPAN LANG="da-DK">   public void destroyApp(boolean unconditional) {}</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><H3 CLASS="western">
13.3.1 <a name='afsn13.3.1'></a>Klassen Canvas</H3>
<P CLASS="western">Klassen Canvas (der arver fra Displayable) er
beregnet til at nedarve fra. 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Metoder
i klassen Canvas, der kan kaldes af programm&oslash;ren</I></FONT></P>
<P CLASS="klasseovs-komp-indryk-western">boolean
isDoubleBuffered()      om telefonen bruger dobbelt tegnebuffer til j&aelig;vn
grafik</P>
<P CLASS="klasseovs-komp-indryk-western">boolean
hasPointerEvents()      om telefonen har en pegeenhed (tryk og
slip-h&aelig;ndelser)</P>
<P CLASS="klasseovs-komp-indryk-western">boolean
hasPointerMotionEvents()    om telefonen har en pegeenhed, der har
tr&aelig;k-h&aelig;ndelser</P>
<P CLASS="klasseovs-komp-indryk-western">boolean
hasRepeatEvents()      om tasterne kan repetere (se keyRepeated()
senere)</P>
<P CLASS="klasseovs-komp-indryk-western">String getKeyName(int
tastkode)    overs&aelig;tter en tastkode til en streng, der beskriver
tasten</P>
<P CLASS="klasseovs-komp-indryk-western">int getGameAction(int
tastkode)    overs&aelig;tter en tastkode til handling (f.eks. i et
spil)</P>
<P CLASS="klasseovs-komp-indryk-western">int getKeyCode(int
handling)    overs&aelig;tter en handling (f.eks. i et spil) til en
tastkode<BR>tastkode&gt;0 svarer til unikode-tegnet, s&aring;
tegn=(char)tastkode<BR>tastkoder p&aring; telefonen:    KEY_NUM0, ...
, KEY_NUM9, KEY_STAR, KEY_POUND  <BR>handlinger (spilknapper):  UP,
DOWN, LEFT, RIGHT, FIRE, GAME_A, ... , GAME_D</P>
<P CLASS="klasseovs-komp-indryk-western">void
setFullScreenMode(boolean)    s&aelig;tter fuldsk&aelig;rmstilstand
(uden titel, menuer etc.)</P>
<P CLASS="klasseovs-komp-indryk-western">void repaint()      beder
systemet om at gentegne hele sk&aelig;rmen</P>
<P CLASS="klasseovs-komp-indryk-western">void repaint(x, y, br,
h&oslash;)      beder systemet om at gentegne et omr&aring;de af sk&aelig;rmen</P>
<P CLASS="klasseovs-komp-indryk-western">void
serviceRepaints()      gennemtvinger evt. ventende gentegninger omg&aring;ende</P>
<H4 CLASS="western">Metoder p&aring; Canvas, som systemet kalder</H4>
<P CLASS="western">De f&oslash;lgende metoder kan du definere i
nedarvingen. Systemet kalder dem p&aring; bestemte tidspunkter. <SPAN LANG="da-DK">De
kan alts&aring; tilsides&aelig;ttes for at f&aring; kaldt noget kode
i bestemte tilf&aelig;lde:</SPAN></P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Tomme
metoder som systemet kalder i Canvas (beregnet til, at programm&oslash;ren
definerer dem)</I></FONT></P>
<PRE CLASS="ikke-javakode-western"><I>  // <B>skal</B> defineres. Kaldes, n&aring;r sk&aelig;rmbilledet skal gentegnes</I>
  protected void paint(Graphics g)

<I>  // Kaldes med en tastkode, n&aring;r brugeren ... </I>
  protected void keyPressed(int tast)   <I>// trykker en tast ned</I>
  protected void keyRepeated(int tast)  <I>// holder en tast nede, s&aring; den repeterer</I>
  protected void keyReleased(int tast)  // n&aring;r brugeren slipper tasten igen

<I>  // Kaldes n&aring;r en evt. pegeenhed (f.eks. en mus) ... </I>
  protected void pointerPressed(x,y)    <I>// trykkes ned (a la mousePressed)</I>
  protected void pointerDragged(x,y)    <I>// tr&aelig;kkes nedtrykket (a la mouseDragged)</I>
  protected void pointerReleased(x,y)   <I>// slippes (a la mouseReleased)</I>

<I>  // Kaldes lige f&oslash;r sk&aelig;rmbilledet bliver vist (bliver synligt p&aring; sk&aelig;rmen)</I>
  protected void showNotify()
<I>  // Kaldes lige efter at sk&aelig;rmbilledet er blevet skjult (ikke mere er synligt)</I>
  protected void hideNotify()

<I>  // Kaldtes n&aring;r sk&aelig;rmbilledet skifter st&oslash;rrelse (f.eks. til fuld sk&aelig;rm)</I>
  protected void sizeChanged(int nyBredde, int nyH&oslash;jde)</PRE><H3 CLASS="western">
13.3.2 <a name='afsn13.3.2'></a>Klassen GameCanvas og lagdelt grafik</H3>
<P CLASS="western">Klassen GameCanvas, der findes pakken
javax.microedition.lcdui.game, er endnu mere specialiseret mod spil.
Den udvider Canvas med faciliteter som dobbeltbuffer (at grafikken
f&oslash;rst tegnes i en separat tegnebuffer og derefter vises p&aring;
sk&aelig;rmen for at opn&aring; mere flydende grafik) og tastestatus
(om en tast er holdt nede eller ej).</P>
<P CLASS="western">I samme pakke findes ogs&aring; underst&oslash;ttelse
for lagdelt grafik. Det er interessant, n&aring;r man skal tegne
f.eks. en bane og nogle bev&aelig;gelige figurer p&aring; banen
(kaldet sprites).</P>
<H3 CLASS="western" STYLE="">13.3.3 <a name='afsn13.3.3'></a>Klassen
Graphics</H3>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Graphics</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">final int HCENTER, LEFT,
RIGHT            horisontal justering</P>
<P CLASS="klasseoversigt---kompakt-western">final int VCENTER, TOP,
BOTTOM, BASELINE    vertikal justering</P>
<P CLASS="klasseoversigt---kompakt-western">void translate(int x, int
y)              s&aelig;t forskydning</P>
<P CLASS="klasseoversigt---kompakt-western">int getTranslateX(),
getTranslateY()          afl&aelig;s forskydning</P>
<P CLASS="klasseoversigt---kompakt-western">void setColor(int
farve)              s&aelig;t farve</P>
<P CLASS="klasseoversigt---kompakt-western">void setColor(int r, int
g, int b)</P>
<P CLASS="klasseoversigt---kompakt-western">void setGrayScale(int
farve)</P>
<P CLASS="klasseoversigt---kompakt-western">int
getColor()                afl&aelig;s farve</P>
<P CLASS="klasseoversigt---kompakt-western">int getRedComponent(),
getGreenComponent(), getBlueComponent(), getGrayScale()</P>
<P CLASS="klasseoversigt---kompakt-western">int getDisplayColor(int
farve)            giver en farves faktiske tegnefarve p&aring; sk&aelig;rm</P>

<P CLASS="klasseoversigt---kompakt-western">final int SOLID,
DOTTED              linjetyper (ubrudt eller stiplet linje)</P>
<P CLASS="klasseoversigt---kompakt-western">void setStrokeStyle(int
linjetype)            s&aelig;tter  linjetypen</P>
<P CLASS="klasseoversigt---kompakt-western">int
getStrokeStyle()                afl&aelig;ser linjetype</P>

<P CLASS="klasseoversigt---kompakt-western">void
setFont(Font)                skrifttypen</P>
<P CLASS="klasseoversigt---kompakt-western">Font getFont()</P>

<P CLASS="klasseoversigt---kompakt-western">void setClip(int x, int
y, int br, int h&oslash;)          s&aelig;t klipning (hvor der skal
tegnes)</P>
<P CLASS="klasseoversigt---kompakt-western">int getClipX(),
getClipY(), getClipWidth(), getClipHeight()</P>
<P CLASS="klasseoversigt---kompakt-western">void clipRect(int x, int
y, int b, int h)          tilf&oslash;j klipnings-rektangel</P>

<P CLASS="klasseoversigt---kompakt-western">void drawLine(int x, int
y, int x2, int y2)</P>
<P CLASS="klasseoversigt---kompakt-western">void fillRect(int x, int
y, int bredde, int h&oslash;jde)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawRect(int x, int
y, int bredde, int h&oslash;jde)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawRoundRect(int x,
int y, int bredde, int h&oslash;jde, int buebredde, int bueh&oslash;jde)</P>
<P CLASS="klasseoversigt---kompakt-western">void fillRoundRect(int x,
int y, int bredde, int h&oslash;jde, int buebredde, int bueh&oslash;jde)</P>
<P CLASS="klasseoversigt---kompakt-western">void fillArc(<SPAN STYLE="font-weight: medium">int
x, int y, int bredde, int h&oslash;jde, int startvinkel, int
buevinkel)</SPAN></P>
<P CLASS="klasseoversigt---kompakt-western">void drawArc(<SPAN STYLE="font-weight: medium">int
x, int y, int bredde, int h&oslash;jde, int startvinkel, int
buevinkel)</SPAN></P>
<P CLASS="klasseoversigt---kompakt-western">void drawString(String
tekst, int x, int y, int ankerpunkt)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawSubstring(String
tekst, int afs&aelig;t, int l&aelig;ngde, int x, int y, int
ankerpunkt)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawChar(char tekst,
int x, int y, int ankerpunkt)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawChars(char[],
tekst, int afs&aelig;t, int l&aelig;ngde, int x, int y, int
ankerpunkt)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawImage(Image
billede, int x, int y, int ankerpunkt)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawRegion(Image
bil, int xBil, int yBil, int br, int h&oslash;, int trans, int x, int
y, int anker)</P>
<P CLASS="klasseoversigt---kompakt-western">void copyArea(int xFra,
int yFra, int br, int h&oslash;, int trans, int x, int y, int anker)</P>
<P CLASS="klasseoversigt---kompakt-western">void fillTriangle(int x1,
int y1, int x2, int y2, int x3, int y3)</P>
<P CLASS="klasseoversigt---kompakt-western">void drawRGB(int[]
farver, int afs, int lgd, int x, int y, int br, int h&oslash;,
boolean gennemsigtig)</P>
<H2 CLASS="western" STYLE="">13.4 <a name='afsn13.4'></a>Grafiske
standardkomponenter</SPAN></H2>
<P CLASS="western">I dette afsnit vil vi gennemg&aring;, hvordan man
kan lave grafiske brugergr&aelig;nseflader v.hj.a.
standardkomponenter (klasserne Form, Alert, List og TextBox og deres
hj&aelig;lpeklasser).</P>
<H3 CLASS="western">13.4.1 <a name='afsn13.4.1'></a>Eksempel: G&aelig;t et tal</H3>
<P CLASS="western">Det f&oslash;lgende eksempel er det klassiske spil
'g&aelig;t tallet jeg t&aelig;nker p&aring;', hvor brugeren skal
g&aelig;tte et tal mellem 1 og 100 og hele tiden f&aring;r at vide,
om tallet er h&oslash;jere eller lavere:</P>
<P CLASS="western"><IMG SRC="bog14_html_m6f28ebdd.png" NAME="Grafik23" ALIGN=BOTTOM BORDER=0>
 
<IMG SRC="bog14_html_m24e0d884.png" NAME="Grafik24" ALIGN=BOTTOM BORDER=0>
 
<IMG SRC="bog14_html_m6473aa8a.png" NAME="Grafik25" ALIGN=BOTTOM BORDER=0>
 
<IMG SRC="bog14_html_13a0d716.png" NAME="Grafik26" ALIGN=BOTTOM BORDER=0>
 ...   
<IMG SRC="bog14_html_m4734e8a3.png" NAME="Grafik27" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Det fungerer ved at bruge en formular (Form) med
med to elementer, en streng (StringItem) og et indtastningsfelt
(TextField).</P>
<PRE CLASS="kode-western">import javax.microedition.midlet.*;
<SPAN LANG="da-DK">import javax.microedition.lcdui.*;</SPAN>
<SPAN LANG="da-DK">import java.util.*;</SPAN>

<SPAN LANG="da-DK">public class GaetEtTalMidletMIDlet extends MIDlet implements CommandListener</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private Display display = Display.getDisplay(this);</SPAN>

<SPAN LANG="da-DK">  private Form f        = new Form(&quot;G&aelig;t tallet jeg t&aelig;nker p&aring;&quot;);</SPAN>
<SPAN LANG="da-DK">  private StringItem si = new StringItem(null, null);</SPAN>
<SPAN LANG="da-DK">  private TextField tf  = new TextField(null, &quot;&quot;, 2, TextField.NUMERIC);</SPAN>

<SPAN LANG="da-DK">  private Command afslutCommand = new Command(&quot;Afslut&quot;, Command.SCREEN, 2);</SPAN>
<SPAN LANG="da-DK">  private Command okCommand = new Command(&quot;OK&quot;, Command.SCREEN, 1);</SPAN>
<SPAN LANG="da-DK">  private Command nytSpilCommand = new Command(&quot;Nyt spil&quot;, Command.SCREEN, 1);</SPAN>

<SPAN LANG="da-DK">  private Random tilf = new Random();</SPAN>
<SPAN LANG="da-DK">  private int tallet;</SPAN>
<SPAN LANG="da-DK">  private int fors&oslash;g;</SPAN>


<SPAN LANG="da-DK">  public GaetEtTalMidletMIDlet() {</SPAN>
<SPAN LANG="da-DK">    f.addCommand(afslutCommand);</SPAN>
<SPAN LANG="da-DK">    f.addCommand(okCommand);</SPAN>
<SPAN LANG="da-DK">    </SPAN>
<SPAN LANG="da-DK"><I>    // tilf&oslash;j klassen (implementerer CommandListener) som lytter til formularen</I></SPAN>
<SPAN LANG="da-DK">    f.setCommandListener(this);</SPAN>

<SPAN LANG="da-DK">    f.append(si);  <I>// tilf&oslash;j strengen</I> til formularen</SPAN>
<SPAN LANG="da-DK">    f.append(tf);  <I>// tilf&oslash;j indtastningsfeltet</I></SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  private void nytSpil() {</SPAN>
<SPAN LANG="da-DK">    tallet = Math.abs(tilf.nextInt()) % 100 + 1; <I>// et tal mellem 1 og 100</I></SPAN>
<SPAN LANG="da-DK">    fors&oslash;g = 0;</SPAN>
<SPAN LANG="da-DK">    si.setText(&quot;Tallet er mellem 1 og 100.&quot;);</SPAN>
<SPAN LANG="da-DK">    tf.setLabel(&quot;Skriv dit g&aelig;t:&quot;);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void startApp() {    <I>// kaldes lige efter konstrukt&oslash;ren</I></SPAN>
<SPAN LANG="da-DK">    nytSpil();</SPAN>
<SPAN LANG="da-DK">    display.setCurrent(f);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void pauseApp() { }</SPAN>

<SPAN LANG="da-DK">  public void destroyApp(boolean unconditional) { }</SPAN>

<SPAN LANG="da-DK"><I>  /**</I></SPAN>
<SPAN LANG="da-DK"><I>   * Reag&eacute;r p&aring; kommandoerne ok, afslut og nyt spil.</I></SPAN>
<SPAN LANG="da-DK"><I>   * Metode skal defineres fordi klassen implementerer CommandListener-interfacet</I></SPAN>
<SPAN LANG="da-DK"><I>   * og den bliver kaldt fordi formularen har f&aring;et tilf&oslash;jet klassen som lytter.</I></SPAN>
<SPAN LANG="da-DK"><I>   * Ved afslut ryddes op og midletten giver besked p&aring; at den skal smides v&aelig;k.</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  public void commandAction(Command c, Displayable s) {</SPAN>
<SPAN LANG="da-DK">    if (c == afslutCommand) {</SPAN>
<SPAN LANG="da-DK">      destroyApp(false);</SPAN>
<SPAN LANG="da-DK">      notifyDestroyed();</SPAN>
<SPAN LANG="da-DK">    } </SPAN>
<SPAN LANG="da-DK">    else if (c == okCommand) {</SPAN>
<SPAN LANG="da-DK">      int g&aelig;t = Integer.parseInt( tf.getString() );</SPAN>
<SPAN LANG="da-DK">      tf.setString(&quot;&quot;);</SPAN>
<SPAN LANG="da-DK">      fors&oslash;g++;</SPAN>
<SPAN LANG="da-DK">      if (g&aelig;t &lt; tallet) si.setText(&quot;Det er h&oslash;jere end &quot;+g&aelig;t+&quot;!&quot;);</SPAN>
<SPAN LANG="da-DK">      else if (g&aelig;t &gt; tallet) si.setText(&quot;Det er lavere end &quot;+g&aelig;t+&quot;!&quot;);</SPAN>
<SPAN LANG="da-DK">      else {</SPAN>
<SPAN LANG="da-DK">        si.setText(&quot;Rigtig p&aring; &quot;+fors&oslash;g+&quot; fors&oslash;g!&quot;);</SPAN>
<SPAN LANG="da-DK">        f.delete(1);      <I>// Fjern indtastningsfeltet fra formularen</I></SPAN>
<SPAN LANG="da-DK">        f.removeCommand(okCommand);</SPAN>
<SPAN LANG="da-DK">        f.addCommand(nytSpilCommand);</SPAN>
<SPAN LANG="da-DK">      }</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    else if (c == nytSpilCommand) {</SPAN>
<SPAN LANG="da-DK">      f.removeCommand(nytSpilCommand);</SPAN>
<SPAN LANG="da-DK">      f.addCommand(okCommand);</SPAN>
<SPAN LANG="da-DK">      f.append(tf);       <I>// Tilf&oslash;j indtastningsfeltet til formularen igen</I></SPAN>
<SPAN LANG="da-DK">      nytSpil();</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<H3 CLASS="western">13.4.2 <a name='afsn13.4.2'></a>Kommandoer og h&aelig;ndelser i midletter</H3>
<P CLASS="western"><SPAN LANG="da-DK">Hver af brugerens mulige
handlinger repr&aelig;senteres af et Command-objekt.</SPAN> I '<SPAN LANG="da-DK">G&aelig;t
et tal'-eksemplet ovenfor var de mulige handlinger 'Afslut', 'OK' og
'Nyt spil'.</SPAN></P>
<P CLASS="western">Command-objektet har et navn (kort tekst, der
vises p&aring; sk&aelig;rmen), en valgfri l&aelig;ngere tekst, en
type (der kan indvirke p&aring; hvordan kommandoen vises) og en
prioritet.</P>
<P CLASS="western"><SPAN LANG="da-DK">Kommandoernes </SPAN>indbyrdes
placering afg&oslash;res af deres prioritet. Afh&aelig;ngig af
telefonens udformning kan det ske at den ikke kan vise alle
kommandoerne. F&oslash;rste prioritet vises altid, mens kommandoer
med anden- og tredieprioritet m&aring;ske kun kan vises i en
undermenu. 
</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Command repr&aelig;senterer en mulig handling brugeren kan foretage</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">static int BACK, CANCEL,
EXIT, HELP, ITEM, OK, SCREEN, STOP      kommandotyper</P>
<P CLASS="klasseoversigt---kompakt-western">Command(String navn, int
type, int prioritet)                  konstrukt&oslash;r</P>
<P CLASS="klasseoversigt---kompakt-western">Command(String navn,
String langtNavn, int kommandoType, int prioritet)  konstrukt&oslash;r</P>
<P CLASS="klasseoversigt---kompakt-western">int
getCommandType()    giver typen af kommandoen</P>
<P CLASS="klasseoversigt---kompakt-western">String getLabel()      giver
navnet p&aring; kommandoen</P>
<P CLASS="klasseoversigt---kompakt-western">String
getLongLabel()    giver det lange navn p&aring; kommandoen</P>
<P CLASS="klasseoversigt---kompakt-western">int getPriority()      giver
prioriteten i forhold til andre kommandoer (1 er h&oslash;jest)</P>
<P CLASS="western">Kommandoer skal f&oslash;jes til et sk&aelig;rmbillede,
hvorefter de vises nederst som mulige handlinger, brugeren kan g&oslash;re:</P>
<PRE CLASS="kode-western">    sk&aelig;rmbillede.addCommand(okCommand);</PRE><P CLASS="western">
Man skal s&aelig;tte en lytter (der skal implementere
CommandListener) p&aring; sk&aelig;rmbilledet</P>
<PRE CLASS="kode-western">    sk&aelig;rmbillede.setCommandListener( lytter );</PRE><P CLASS="western">
Interfacet CommandListener har metoden commandAction(), der bliver
kaldt, hvis brugeren v&aelig;lger handlingen, som Command-objektet
repr&aelig;senterer.</P>
<H3 CLASS="western">13.4.3 <a name='afsn13.4.3'></a>TextBox</H3>
<P CLASS="western">En TextBox giver brugeren mulighed for at indtaste
og redigere tekst.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
TextBox (arver fra Displayable)</I></FONT></P>
<P CLASS="klasseovs-komp-indryk-western">TextBox(String titel,String
tekst,int maxst&oslash;rrelse,int type) opretter en TextBox, hvor
type kan v&aelig;re:<BR>ANY, EMAILADDR, NUMERIC, PHONENUMBER, URL,
DECIMAL, PASSWORD, <BR>SENSITIVE, UNEDITABLE, NON_PREDICTIVE,
<BR>INITIAL_CAPS_WORD, INITIAL_CAPS_SENTENCE</P>
<P CLASS="klasseovs-komp-indryk-western">String getString()          giver
TextBoxens indhold som en streng</P>
<P CLASS="klasseovs-komp-indryk-western">void setString(String
nytIndhold)        s&aelig;tter indholdet</P>
<P CLASS="klasseovs-komp-indryk-western">int
getChars(char[])          giver TextBoxens indhold som et array af char</P>
<P CLASS="klasseovs-komp-indryk-western">void setChars(char[]
nytIndhold, int afs, int lgd)  erstatter teksten med indholdet
nytIndhold</P>
<P CLASS="klasseovs-komp-indryk-western">void insert(String tekst,
int position)       s&aelig;tter en tekst ind lige f&oslash;r den
angivne position</P>
<P CLASS="klasseovs-komp-indryk-western">void insert(char[] data, int
afs, int lgd, int position) ditto. 
</P>
<P CLASS="klasseovs-komp-indryk-western">void delete(int afs, int
lgd)          sletter <I>lgd</I> tegn startende fra <I>afs</I>  </P>
<P CLASS="klasseovs-komp-indryk-western">int getMaxSize()          giver
maksimale antal tegn, der er plads til</P>
<P CLASS="klasseovs-komp-indryk-western">int
setMaxSize(int)          s&aelig;tter det maksimale antal tegn</P>
<P CLASS="klasseovs-komp-indryk-western">int size()          giver
antallet af tegn, der er i tekstboksen lige nu</P>
<P CLASS="klasseovs-komp-indryk-western">int
getCaretPosition()          returnerer mark&oslash;rens aktuelle position</P>
<P CLASS="klasseovs-komp-indryk-western">void
setConstraints(int)          s&aelig;tter type (ANY, EMAILADDR, NUMERIC,
...)</P>
<P CLASS="klasseovs-komp-indryk-western">int
getConstraints()          giver den aktuelle type</P>
<P CLASS="klasseovs-komp-indryk-western">void
setInitialInputMode(String m&aring;de)       vink til inputm&aring;de
(f.eks. store bogstaver)</P>

<H3 CLASS="western">13.4.4 <a name='afsn13.4.4'></a>Alert</H3>
<P CLASS="western">En Alert er en klasse, der viser data til
brugeren, og venter et bestemt tidsrum, f&oslash;r det n&aelig;ste
sk&aelig;rmbillede vises. Et Alert-sk&aelig;rmbillede kan vise tekst
og billede og kan modtage brugerinput som andre sk&aelig;rmbilleder.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Alert (arver fra Displayable)</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">Alert(String
titel)        opretter en Alert med den givne titel<BR>Alert(String
titel,String tekst,Image billede,AlertType alerttype) ditto</P>
<P CLASS="klasseoversigt---kompakt-western">static Command
DISMISS_COMMAND kommando, der angiver, at brugeren har lukket alerten</P>
<P CLASS="klasseoversigt---kompakt-western">int
getDefaultTimeout()      returnerer standardtiden, alerten vises</P>
<P CLASS="klasseoversigt---kompakt-western">void setTimeout(int tid i
millisek eller FOREVER) s&aelig;tter, hvor l&aelig;nge alerten vises</P>
<P CLASS="klasseoversigt---kompakt-western">int
getTimeout()        returnerer, hvor l&aelig;nge alerten vises</P>
<P CLASS="klasseoversigt---kompakt-western">void
setType(AlertType)      s&aelig;tter typen af alerten</P>
<P CLASS="klasseoversigt---kompakt-western"><SPAN LANG="da-DK">AlertType
getType()        returnerer typen af alerten (typen <FONT FACE="Palatino">kan
v&aelig;re </FONT></SPAN><CODE CLASS="western"><SPAN LANG="da-DK"><FONT FACE="Palatino">INFO</FONT></SPAN></CODE><SPAN LANG="da-DK"><FONT FACE="Palatino">,<BR>        </FONT></SPAN><CODE CLASS="western"><SPAN LANG="da-DK"><FONT FACE="Palatino">WARNING</FONT></SPAN></CODE><SPAN LANG="da-DK"><FONT FACE="Palatino">,
</FONT></SPAN><CODE CLASS="western"><SPAN LANG="da-DK"><FONT FACE="Palatino">ERROR</FONT></SPAN></CODE><SPAN LANG="da-DK"><FONT FACE="Palatino">,
</FONT></SPAN><CODE CLASS="western"><SPAN LANG="da-DK"><FONT FACE="Palatino">ALARM</FONT></SPAN></CODE><SPAN LANG="da-DK"><FONT FACE="Palatino">,
og </FONT></SPAN><CODE CLASS="western"><SPAN LANG="da-DK"><FONT FACE="Palatino">CONFIRMATION)</FONT></SPAN></CODE></P>
<P CLASS="klasseoversigt---kompakt-western">void
setString(String)      s&aelig;tter teksten</P>
<P CLASS="klasseoversigt---kompakt-western">String
getString()        returnerer teksten i alerten</P>
<P CLASS="klasseoversigt---kompakt-western">void
setImage(Image)      s&aelig;tter alerten til ogs&aring; at vise et
billedet</P>
<P CLASS="klasseoversigt---kompakt-western">Image
getImage()        returnerer et evt. tidligere sat billede</P>
<P CLASS="klasseoversigt---kompakt-western">void
setIndicator(Gauge)      s&aelig;tter alerten til ogs&aring; at vise en
&quot;progress bar&quot;</P>
<P CLASS="klasseoversigt---kompakt-western">Gauge
getIndicator()      returnerer en evt. tidligere sat &quot;progress bar&quot;</P>
<H3 CLASS="western" ALIGN=LEFT>13.4.5 <a name='afsn13.4.5'></a>List</H3>
<P CLASS="western">En List er et sk&aelig;rmbillede med en liste af
valgmuligheder, som brugeren kan navigere op og ned i. 
</P>
<P CLASS="western">Lister kan fungere p&aring; 3 m&aring;der:</P>
<UL>
  <LI><P CLASS="western">EXCLUSIVE: Listens elementer vises som
  radioknapper (hvor h&oslash;jst &eacute;t element kan v&aelig;re
  valgt ad gangen). 
  </P>
  <LI><P CLASS="western">MULTIPLE: Listens elementer vises som
  afkrydsningsfelter (flere elementer kan v&aelig;re valgt ad gangen).
    </P>
  <LI><P CLASS="western">IMPLICIT: Listens elementer vises som en
  valgliste. List.IMPLICIT er speciel ved, at den har en
  foruddefineret Command, som hedder SELECT_COMMAND. 
  </P>
</UL>
<P CLASS="western">Programm&oslash;ren kan selv, v&aelig;lge hvilke
handlinger brugeren kan lave med hvert element, ved at definere nogle
Command-objekter (se <a href='kapitel13.jsp#afsn13.4.2'>afsnit 13.4.2</a>) og tilf&oslash;je dem med
addCommand(Command c) p&aring; listen. Derefter skal metoden
setCommandListener(CommandListener lytter) kaldes med en lytter, der
skal h&aring;ndtere, hvis brugeren v&aelig;lger at udf&oslash;re en
handling p&aring; et af elementerne i listen.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
List (arver fra Displayable)</I></FONT></P>
<P CLASS="klasseovs-komp-indryk-western">static int EXCLUSIVE,
MULTIPLE, IMPLICIT    listens type</P>
<P CLASS="klasseovs-komp-indryk-western">static Command
SELECT_COMMAND        standardkommando for IMPLICIT-lister</P>
<P CLASS="klasseovs-komp-indryk-western">List(String titel, int
type)            konstrukt&oslash;r til ny liste</P>
<P CLASS="klasseovs-komp-indryk-western">List(String titel ,int
type,String[] tekster, Image[] billeder) ny liste med tekst og
billeder</P>
<P CLASS="klasseovs-komp-indryk-western">String getString(int
elementnr)          giver strengen, der st&aring;r p&aring; <I>elementnr</I>
i listen</P>
<P CLASS="klasseovs-komp-indryk-western">Image getImage(int
elementnr)          giver billedet p&aring; plads nr. <I>elementnr</I>          </P>
<P CLASS="klasseovs-komp-indryk-western">void set(int elementnr,
String tekst, Image billede)  s&aelig;tter indholdet af listen p&aring;
plads nr. <I>elementnr</I></P>
<P CLASS="klasseovs-komp-indryk-western">int append(String tekst,
Image billede)        tilf&oslash;jer et nyt element i enden af listen</P>
<P CLASS="klasseovs-komp-indryk-western">void insert(int elementnr,
String tekst, Image billede) inds&aelig;tter et nyt element lige f&oslash;r
<I>elementnr</I></P>
<P CLASS="klasseovs-komp-indryk-western">void delete(int
elementnr)            sletter elementet p&aring; elementnr  </P>
<P CLASS="klasseovs-komp-indryk-western">void
deleteAll()            sletter alle elementer i listen</P>
<P CLASS="klasseovs-komp-indryk-western">int size()            returnerer
antallet af elementer</P>
<P CLASS="klasseovs-komp-indryk-western">void setFitPolicy(int
politik)          bestemmer, hvordan elementerne organiseres.<BR>mulighederne
er: Choice.TEXT_WRAP_DEFAULT, TEXT_WRAP_ON og TEXT_WRAP_OFF</P>
<P CLASS="klasseovs-komp-indryk-western">int
getFitPolicy()            giver den aktuelle organisering af elementer</P>
<P CLASS="klasseovs-komp-indryk-western">void setFont(int,
Font)            s&aelig;tter skrifttypen</P>
<P CLASS="klasseovs-komp-indryk-western">Font getFont(int)            giver
den aktuelle skrifttype</P>
<P CLASS="klasseovs-komp-indryk-western">boolean
isSelected(int)            returnerer sand, hvis elementet er valgt</P>
<P CLASS="klasseovs-komp-indryk-western">int
getSelectedIndex()            returnerer index for det valgte element</P>
<P CLASS="klasseovs-komp-indryk-western">int
getSelectedFlags(boolean[] valgte)        giver antal valgte elementer og
s&aelig;tter valg. <BR>  (arrayet skal mindst have et antal pladser
svarende til antallet af elementer i listen)</P>
<P CLASS="klasseovs-komp-indryk-western">void setSelectedIndex(int
elementnr, boolean valgt)  s&aelig;t elementnr til at v&aelig;re valgt
</P>
<P CLASS="klasseovs-komp-indryk-western">void
setSelectedFlags(boolean[] valgteelementer)   s&aelig;tter de valgte
elementer i listen</P>
<P CLASS="klasseovs-komp-indryk-western">void
setSelectCommand(Command)         tilsides&aelig;tter List.SELECT_COMMAND
med en anden kommando  (kun for type=List.IMPLICIT)</P>

<H3 CLASS="western">13.4.6 <a name='afsn13.4.6'></a>Form</H3>
<P CLASS="western">Med en Form kan man sammens&aelig;tte billeder,
tekstfelter og lister, som man lyster.</P>
<P CLASS="western">En Form er en indtastningsformular, der kan
indeholde forskellige felter: (Item-objekter), s&aring;som:
ImageItem, StringItem, CustomItem (som man kan arve fra og lave sine
egne slags formular-elementer), ChoiceGroup, TextField, DateField,
Gauge og Spacer. 
</P>
<P CLASS="western"><IMG SRC="bog14_html_m23acefb1.gif" NAME="Grafik53" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">En Form kan have et ItemStateListener-objekt
tilknyttet, der lytter efter &aelig;ndringer i formularens felter, og
et ItemCommandListener, der lytter efter, om brugeren fors&oslash;ger
at udf&oslash;re en kommando p&aring; et af formularens elementer.</P>

<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Form (arver fra Displayable)</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">Form(String
titel)    opretter en ny Form med den angivne titel</P>
<P CLASS="klasseoversigt---kompakt-western">Form(String,Item[])    opretter
en ny Form med den angivne titel og Item-objekter</P>
<P CLASS="klasseoversigt---kompakt-western">int
append(Item)    tilf&oslash;jer et nyt Item til Form-objektet</P>
<P CLASS="klasseoversigt---kompakt-western">int
append(String)    tilf&oslash;jer en streng til formularen</P>
<P CLASS="klasseoversigt---kompakt-western">int
append(Image)    tilf&oslash;jer et billede til formularen</P>
<P CLASS="klasseoversigt---kompakt-western">void insert(int itemnr,
Item) Inds&aelig;tter et Item-objekt p&aring; pladsen specificeret
ved <I>Itemnr</I></P>
<P CLASS="klasseoversigt---kompakt-western">void delete(int
itemnr)  sletter Item-objektet p&aring; den angivne plads</P>
<P CLASS="klasseoversigt---kompakt-western">void deleteAll()    sletter
alle Item-objekter i Formen</P>
<P CLASS="klasseoversigt---kompakt-western">void set(int itemnr, Item
nytItem)  Udskifter Item p&aring; plads nr <I>itemnr</I> med det nye
Item</P>
<P CLASS="klasseoversigt---kompakt-western">Item get(int
itemnr)    returnerer elementet p&aring; plads nr. <I>itemnr</I></P>
<P CLASS="klasseoversigt---kompakt-western">void
setItemStateListener(ItemStateListener l) s&aelig;tter den nye
lytter, hvorved den gamle slettes.</P>
<P CLASS="klasseoversigt---kompakt-western">int size()    returnerer
antallet af Items i Formen</P>
<P CLASS="klasseoversigt---kompakt-western">int getWidth()    giver
bredden i punkter af det areal, der er til r&aring;dighed i
formularen</P>
<P CLASS="klasseoversigt---kompakt-western">int getHeight()    giver
h&oslash;jden i punkter af det areal, der er til r&aring;dighed i
formularen</P>


<H2 CLASS="western" STYLE="">13.5 <a name='afsn13.5'></a>Tilg&aelig;ngelige
klasser fra J2SE</SPAN></H2>
<P CLASS="western">De f&oslash;lgende pakker og klasser fra Javas
standardbibliotek (J2SE) er ogs&aring; tilg&aelig;ngelige for
midletter.</P>
<H3 CLASS="western">13.5.1 <a name='afsn13.5.1'></a>Pakken java.lang</H3>
<P CLASS="western">I pakken java.lang findes stort set alle de kendte
klasser, man forventer fra J2SE. 
</P>
<P CLASS="western">Det er, ud over forskellige klasser til at
h&aring;ndtere undtagelser (nedarvinger fra Exception eller
Throwable), klasserne:</P>
<UL>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Object,
  Class, Thread, Runnable, System, Runtime og Math</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">String
  og StringBuffer</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Klasserne,
  der repr&aelig;senterer de simple typer: Boolean, Short, Byte,
  Character, Long og Integer</P>
</UL>
<H3 CLASS="western">13.5.2 <a name='afsn13.5.2'></a>Pakken java.util</H3>
<P CLASS="western">I pakken java.util findes klasserne kendt fra J2SE
(undtaget er dog klasserne til samlinger af data,
Collections-klasserne, s&aring;som List, ArrayList, Set, Map, ...):</P>
<UL>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Vector,
  Hashtable, Stack og Enumeration</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Date,
  TimeZone og Calendar</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">TimerTask
  og Timer</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Random</P>
</UL>
<H3 CLASS="western">13.5.3 <a name='afsn13.5.3'></a>Pakken java.io</H3>
<P CLASS="western">I pakken java.io findes de almindelige klasser til
IO-h&aring;ndtering, dog uden dem, der er beregnet til filh&aring;ndtering
(da man ikke kan gemme filer p&aring; en mobiltelefon).</P>
<P CLASS="western">Disse er (excl. klasser til at h&aring;ndtere
undtagelser): 
</P>
<UL>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">InputStream,
  ByteArrayInputStream, DataInput og DataInputStream</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Reader,
  InputStreamReader</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">OutputStream,
  ByteArrayOutputStream, DataOutput og DataOutputStream</P>
  <LI><P CLASS="western" STYLE="margin-top: 0cm; margin-bottom: 0cm">Writer,
  OutputStreamWriter, PrintStream</P>
</UL>

<P CLASS="western">I <a href='kapitel13.jsp#afsn13.6.1'>afsnit 13.6.1</a> beskrives de ekstra IO-klasser til
netv&aelig;rkskommunikation, som er tilg&aelig;ngelige p&aring; en
mobiltelefon.</P>
<P CLASS="western">Har man brug for at gemme data i telefonen kan man
bruge RMS-systemet, der er beskrevet i <a href='kapitel13.jsp#afsn13.7'>afsnit 13.7</a>.</P>

<H2 CLASS="western" STYLE="">13.6 <a name='afsn13.6'></a>Netv&aelig;rkskommunikation</SPAN></H2>
<P CLASS="western">Midletter kan kommunikere over netv&aelig;rket med
en lang r&aelig;kke protokoller (pr&aelig;cist hvilke der
underst&oslash;ttes afh&aelig;nger af apparatet), hvoraf den mest
udbredte er HTTP-protokollen.</P>
<H3 CLASS="western">13.6.1 <a name='afsn13.6.1'></a>Pakken javax.microedition.io</H3>
<P CLASS="western">I pakken javax.microedition.io ligger en r&aelig;kke
klasser og interfaces til netv&aelig;rkskommunikation, der er
specielt rettet mod sm&aring; apparater som telefoner.</P>
<P CLASS="western">Helt central er klassen Connector, gennem hvilken
man kan &aring;bne en r&aelig;kke forskellige slags forbindelser,
f.eks. en HTTP-forbindelse:</P>
<PRE CLASS="kode-western">  HttpConnection c = (HttpConnection) Connector.open(&quot;http://javabog.dk&quot;);</PRE><P CLASS="western">
Man f&aring;r alts&aring; et Connection-objekt ud, som man derefter
selv m&aring; s&oslash;rge for at typekonvertere til den rigtige
slags forbindelse.</P>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
Connector - alle metoderne kan kaste IOException </I></FONT>
</P>
<P CLASS="klasseoversigt---kompakt-western">static int READ, WRITE,
READ_WRITE              l&aelig;se/skrive-flag</P>
<P CLASS="klasseoversigt---kompakt-western">static Connection
open(String url)                  &aring;bner forbindelse</P>
<P CLASS="klasseoversigt---kompakt-western">static Connection
open(String url, int l&aelig;sSkriv)          do, med l&aelig;se/skrive-flag</P>
<P CLASS="klasseoversigt---kompakt-western">static Connection
open(String url, int l&aelig;sSkriv, boolean udl&oslash;b)  do, men
tjekker for udl&oslash;bstid</P>
<P CLASS="klasseoversigt---kompakt-western">static DataInputStream
openDataInputStream(String url)</P>
<P CLASS="klasseoversigt---kompakt-western">static DataOutputStream
openDataOutputStream(String url) 
</P>
<P CLASS="klasseoversigt---kompakt-western">static InputStream
openInputStream(String url)</P>
<P CLASS="klasseoversigt---kompakt-western">static OutputStream
openOutputStream(String url)</P>
<P CLASS="western">N&aring;r Connector.open() kaldes, er det
parameteren url, der afg&oslash;r, hvilken slags forbindelse der
bliver returneret:</P>
<UL>
  <LI><P CLASS="western">HttpConnection - til
  HTTP-kommunikation<BR>f.eks.: Connector.open(&quot;http://javabog.dk&quot;)</P>
  <LI><P CLASS="western">HttpsConnection - til sikker
  HTTP-kommunikation<BR>f.eks.: Connector.open(&quot;https://javabog.dk&quot;)</P>
  <LI><P CLASS="western">SocketConnection - til at &aring;bne en
  TCP-forbindelse<BR>f.eks.: Connector.open(&quot;socket://host.com:79&quot;)</P>
  <LI><P CLASS="western">ServerSocketConnection - til at lytte p&aring;
  en port efter indkommende forbindelser<BR>f.eks.:
  Connector.open(&quot;socket://:79&quot;)</P>
  <LI><P CLASS="western">SecureConnection - til SSL-forbindelser
  (Secure Socket Layer) <BR>f.eks.:
  Connector.open(&quot;ssl://maskinnavn.dk:79&quot;)</P>
  <LI><P CLASS="western">DatagramConnection<BR>f.eks.:
  Connector.open(&quot;datagram://123.456.789.12:1234&quot;) for
  klientforbindelse<BR>eller: Connector.open(&quot;datagram://:1234&quot;)
  for serverforbindelse, der lytter p&aring; en port</P>
  <LI><P CLASS="western">CommConnection - til eventuelle serielle
  porte<BR>f.eks.: Connector.open(&quot;comm:1&quot;)</P>
</UL>
<P CLASS="western">Connector opretter forbindelser dynamisk ved at
sl&aring; en protokolklasse op, hvis navn best&aring;r af navnet p&aring;
platformen, midletten k&oslash;res fra, og protokolnavnet (fremfindes
ud fra URL'en).</P>
<P CLASS="western">Derudover kan man ogs&aring; angive, om man &oslash;nsker
at l&aelig;se, skrive eller b&aring;de l&aelig;se og skrive til
serveren i open()-metoden:</P>
<PRE CLASS="kode-western">HttpConnection http = (HttpConnection) Connector.open(URL, Connector.READ_WRITE);</PRE><P CLASS="western">
N&aring;r man har oprettet forbindelsen, kan man &aring;bne en
DataOutputStream. Den tillader, at man skriver en tekststreng direkte
til den ved hj&aelig;lp af metoden writeChars():</P>
<PRE CLASS="kode-western">DataOutputStream out = http.openDataOutputStream();
<SPAN LANG="da-DK">out.writeChars(&quot;En tekst&quot;);</SPAN></PRE><P CLASS="western">
Man kunne ogs&aring; f&aring; en bin&aelig;r OutputStream og skrive
til den, men s&aring; ville man i dette tilf&aelig;lde v&aelig;re
n&oslash;dt til at pakke den ind i en PrintWriter(), som konverterer
tekst til bin&aelig;rt format.</P>
<H3 CLASS="western">13.6.2 <a name='afsn13.6.2'></a>Eksempel: Kommunikation med webserver</H3>
<P CLASS="western">Nedenst&aring;ende eksempel illustrerer, hvordan
man kan sende og modtage tekst fra en server.</P>
<P CLASS="western"><SPAN LANG="da-DK">Brugeren kommunikerer med
serveren ved at skrive en tekst, som bliver sendt til serveren.</SPAN>
P&aring; serveren aktiveres JSP-filen <SPAN LANG="da-DK">modtag_besked.jsp
 (Java Server Pages, se <a href='kapitel14.jsp#afsn14.2'>afsnit 14.2</a>):</SPAN></P>
<PRE CLASS="kode-western">&lt;%@ page language = &quot;java&quot; import=&quot;java.io.*&quot;%&gt;
<SPAN LANG="da-DK">&lt;%</SPAN>
<SPAN LANG="da-DK">  BufferedReader in = request.getReader();</SPAN>
<SPAN LANG="da-DK">  String besked = in.readLine(); <I>// l&aelig;s beskeden</I></SPAN>
<SPAN LANG="da-DK">  out.print(besked);      <I>// ... og send den tilbage igen!</I></SPAN>
<FONT SIZE=1 STYLE="font-size: 2pt"><FONT COLOR="#d9d9d9"><FONT FACE="Courier, monospace"><FONT SIZE=1 STYLE="font-size: 2pt"><SPAN STYLE="font-weight: medium"><SPAN STYLE="background: transparent"><SPAN LANG="da-DK">//&lt;title&gt;modtag besked&lt;/title&gt;</SPAN></SPAN></SPAN></FONT></FONT></FONT></FONT>
<SPAN LANG="da-DK">%&gt;</SPAN></PRE><P CLASS="western">
JSP-siden p&aring; serveren kvitterer for modtagelsen, ved at sende
teksten tilbage igen.</P>

<P CLASS="western"><IMG SRC="bog14_html_261816f1.png" NAME="Grafik49" ALIGN=MIDDLE BORDER=0>
  
<IMG SRC="bog14_html_m6840a23c.png" NAME="Grafik50" ALIGN=MIDDLE BORDER=0>
  
<IMG SRC="bog14_html_m58d2489c.png" NAME="Grafik47" ALIGN=MIDDLE BORDER=0>
  
<IMG SRC="bog14_html_19029cd4.png" NAME="Grafik48" ALIGN=MIDDLE BORDER=0></P>

<PRE CLASS="kode-western">import javax.microedition.midlet.*;
<SPAN LANG="da-DK">import javax.microedition.lcdui.*;</SPAN>
<SPAN LANG="da-DK">public class BeskedMidlet extends MIDlet</SPAN>
<SPAN LANG="da-DK">{</SPAN>
<SPAN LANG="da-DK">  private static BeskedMidlet instance;</SPAN>
<SPAN LANG="da-DK">  private SendBesked displayable = new SendBesked(this);</SPAN>

<SPAN LANG="da-DK">  public BeskedMidlet() {</SPAN>
<SPAN LANG="da-DK">    instance = this;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void startApp() {</SPAN>
<SPAN LANG="da-DK">    Display.getDisplay(this).setCurrent(displayable);</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void pauseApp() {</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void destroyApp(boolean unconditional) {</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public static void quitApp() {</SPAN>
<SPAN LANG="da-DK">    instance.destroyApp(true);</SPAN>
<SPAN LANG="da-DK">    instance.notifyDestroyed();</SPAN>
<SPAN LANG="da-DK">    instance = null;</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE>
<P CLASS="western">Midletten bruger klassen SendBesked (en TextBox),
der st&aring;r for kommunikation mellem bruger og server:</P>


<PRE CLASS="kode-western">import javax.microedition.lcdui.*;
<SPAN LANG="da-DK">import java.io.*;</SPAN>
<SPAN LANG="da-DK">import javax.microedition.io.*;</SPAN>

<SPAN LANG="da-DK">public class SendBesked extends TextBox implements CommandListener {</SPAN>
<SPAN LANG="da-DK">  private BeskedMidlet midletten;</SPAN>
<SPAN LANG="da-DK">  private Alert a;</SPAN>
<SPAN LANG="da-DK">  public SendBesked(BeskedMidlet midletten)  {</SPAN>
<SPAN LANG="da-DK">    super(&quot;Skriv din besked&quot;, &quot;&quot;, 50, TextField.ANY);</SPAN>
<SPAN LANG="da-DK">    this.midletten=midletten;</SPAN>
<SPAN LANG="da-DK">    setCommandListener(this);</SPAN>
<SPAN LANG="da-DK">    addCommand(new Command(&quot;Exit&quot;, Command.EXIT, 1));</SPAN>
<SPAN LANG="da-DK">    addCommand(new Command(&quot;Send&quot;, Command.OK,1));</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  public void commandAction(Command command, Displayable displayable) {</SPAN>
<SPAN LANG="da-DK">    if(command.getCommandType() == Command.EXIT)</SPAN>
<SPAN LANG="da-DK">      BeskedMidlet.quitApp();</SPAN>
<SPAN LANG="da-DK">    else if(command.getCommandType() == Command.OK) try {</SPAN>
<SPAN LANG="da-DK">      sendData(getString(),&quot;http://localhost:8080/modtag_besked.jsp&quot;);</SPAN>
<SPAN LANG="da-DK">    } catch(IOException e){System.out.println(e);}</SPAN>
<SPAN LANG="da-DK">  }</SPAN>

<SPAN LANG="da-DK">  <I>/**</I></SPAN>
<SPAN LANG="da-DK"><I>   * Afsender en tekststreng til den angivne URL.</I></SPAN>
<SPAN LANG="da-DK"><I>   * Efter afsendelsen af data kaldes metoden l&aelig;sData(), som l&aelig;ser svaret fra</I></SPAN>
<SPAN LANG="da-DK"><I>   * serveren.</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param data den tekst der skal sendes til serveren</I></SPAN>
<SPAN LANG="da-DK"><I>   * @param URL URL&eacute;n til den servlet eller JSP-side, der h&aring;ndterer anmodningen</I></SPAN>
<SPAN LANG="da-DK"><I>   */</I></SPAN>
<SPAN LANG="da-DK">  private void sendData(String data, String URL)throws IOException {</SPAN>
<SPAN LANG="da-DK">    HttpConnection http = null;</SPAN>
<SPAN LANG="da-DK">    try {</SPAN>
<SPAN LANG="da-DK">      http = (HttpConnection) Connector.open(URL, Connector.READ_WRITE);</SPAN>
<SPAN LANG="da-DK">      http.setRequestMethod(HttpConnection.POST);</SPAN>
<SPAN LANG="da-DK">      DataOutputStream out = http.openDataOutputStream();</SPAN>
<SPAN LANG="da-DK">      out.writeChars(data);</SPAN>
<SPAN LANG="da-DK">      out.flush();</SPAN>
<SPAN LANG="da-DK">      l&aelig;sData(http.openDataInputStream());</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    catch (Exception ex) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(ex);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    finally {</SPAN>
<SPAN LANG="da-DK">      http.close();  <I>//husk altid at lukke forbindelsen!</I></SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">  </SPAN>
<SPAN LANG="da-DK"> <I>/**</I></SPAN>
<SPAN LANG="da-DK"><I>  * L&aelig;ser en tekststreng fra den angivne InputStream.</I></SPAN>
<SPAN LANG="da-DK"><I>  * Herefter vises en alert med indholdet af tekststrengen</I></SPAN>
<SPAN LANG="da-DK"><I>  * @param is Indeholder de data, der kommer fra serveren</I></SPAN>
<SPAN LANG="da-DK"><I>  */</I></SPAN>
<SPAN LANG="da-DK">  private void l&aelig;sData(InputStream is) throws IOException {</SPAN>
<SPAN LANG="da-DK">    StringBuffer besked = new StringBuffer();</SPAN>
<SPAN LANG="da-DK">    try {</SPAN>
<SPAN LANG="da-DK">      int bogstav = is.read();</SPAN>
<SPAN LANG="da-DK">      while ( bogstav != -1)</SPAN>
<SPAN LANG="da-DK">      {</SPAN>
<SPAN LANG="da-DK">        besked.append ((char) bogstav);</SPAN>
<SPAN LANG="da-DK">        bogstav = is.read();</SPAN>
<SPAN LANG="da-DK">      }</SPAN>
<SPAN LANG="da-DK">      setString(&quot;&quot;);</SPAN>
<SPAN LANG="da-DK">      a = new Alert(&quot;Besked afsendt!&quot;,besked.toString(),null,AlertType.INFO);</SPAN>
<SPAN LANG="da-DK">      a.setTimeout(5000); <I>//Vis Alerten i 5 sek</I></SPAN>
<SPAN LANG="da-DK">      Display.getDisplay(midletten).setCurrent(a);</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">    catch(Exception e) {</SPAN>
<SPAN LANG="da-DK">      System.out.println(e);</SPAN>
<SPAN LANG="da-DK">    } finally {</SPAN>
<SPAN LANG="da-DK">      if(is!=null) is.close();</SPAN>
<SPAN LANG="da-DK">    }</SPAN>
<SPAN LANG="da-DK">  }</SPAN>
<SPAN LANG="da-DK">}</SPAN></PRE><H2 CLASS="western" STYLE="">
13.7 <a name='afsn13.7'></a>Gemme data i telefonen</SPAN></H2>
<P CLASS="western">Vil man gemme data i mobiltelefonen, skal man
bruge klassen RecordStore fra pakken javax.microedition.rms (Record
Management System). Man kan t&aelig;nke p&aring; det som en begr&aelig;nset
mulighed for at gemme filer i telefonen. 
</P>
<P CLASS="western">Her er et eksempel p&aring; brug:</P>
<PRE CLASS="kode-western"><I>  // &Aring;bn en 'fil' i telefonen. Opret den hvis den ikke allerede findes.</I>
<SPAN LANG="da-DK">  RecordStore database = RecordStore.openRecordStore(&quot;minFil&quot;, true);</SPAN>

<SPAN LANG="da-DK"><I>  // Skaf data i form af et array af byte</I></SPAN>
<SPAN LANG="da-DK">  String strengDerSkalGemmes = &quot;Hej Verden&quot;;</SPAN>
<SPAN LANG="da-DK">  byte[] data =  strengDerSkalGemmes.getBytes();</SPAN>

<SPAN LANG="da-DK"><I>  // gem data</I></SPAN>
<SPAN LANG="da-DK">  database.addRecord( data, 0, data.length );</SPAN>

<SPAN LANG="da-DK"><I>  // luk 'filen'</I></SPAN>
<SPAN LANG="da-DK">  database.closeRecordStore();</SPAN></PRE>
<P ALIGN=CENTER STYLE="margin-top: 0.21cm; margin-bottom: 0cm"><FONT SIZE=2 STYLE="font-size: 9pt"><I>Klassen
RecordStore - n&aelig;sten alle metoderne kan kaste
RecordStoreException (ikke vist)</I></FONT></P>
<P CLASS="klasseoversigt---kompakt-western">static String[]
listRecordStores()        giver navnene p&aring; gemte 'filer' for den
aktuelle midlet</P>
<P CLASS="klasseoversigt---kompakt-western">static void
deleteRecordStore(String navn)  sletter en 'fil'</P>
<P CLASS="klasseoversigt---kompakt-western">static RecordStore
openRecordStore(String navn, boolean opret) &aring;bner og evt.
opretter en 'fil'</P>
<P CLASS="klasseoversigt---kompakt-western">static RecordStore
openRecordStore(String navn, String leverand&oslash;r, String
midletnavn)</P>
<P CLASS="klasseoversigt---kompakt-western">static RecordStore
openRecordStore(String navn, boolean opret, int adgangsflag, boolean
skrivbar)</P>
<P CLASS="klasseoversigt---kompakt-western">static int
AUTHMODE_PRIVATE, AUTHMODE_ANY    adgangsflag</P>

<P CLASS="klasseoversigt---kompakt-western">void setMode(int
adgangsflag, boolean skrivbar)</P>
<P CLASS="klasseoversigt---kompakt-western">String
getName()          giver navnet p&aring; 'filen'</P>
<P CLASS="klasseoversigt---kompakt-western">int
getVersion()          giver versionsnummeret (&aelig;ndres, n&aring;r
'filen' &aelig;ndres)</P>
<P CLASS="klasseoversigt---kompakt-western">int
getNumRecords()        giver antallet af poster i 'filen'
(Recordstore-objektet)</P>
<P CLASS="klasseoversigt---kompakt-western">int getSize()          giver
antallet af byte, som 'filen' optager</P>
<P CLASS="klasseoversigt---kompakt-western">int
getSizeAvailable()        giver, hvor meget ledig 'diskplads' der er i
telefonen</P>
<P CLASS="klasseoversigt---kompakt-western">long
getLastModified()        giver, hvorn&aring;r 'filen' sidst var &aelig;ndret
i (i millisekunder)</P>
<P CLASS="klasseoversigt---kompakt-western">int
getNextRecordID()        giver ID for den n&aelig;ste post</P>
<P CLASS="klasseoversigt---kompakt-western">int addRecord(byte[]
data, int afs, int lgd) tilf&oslash;jer post med (del af) array af
byte, giver et ID retur</P>
<P CLASS="klasseoversigt---kompakt-western">void deleteRecord(int
ID)        sletter post med bestemt ID</P>
<P CLASS="klasseoversigt---kompakt-western">int getRecordSize(int
ID)        giver st&oslash;rrelsen i byte for den givne post</P>
<P CLASS="klasseoversigt---kompakt-western">int getRecord(int ID,
byte[] data, int afs)  gemmer post i et array af byte (afs bestemmer
hvor)</P>
<P CLASS="klasseoversigt---kompakt-western">byte[] getRecord(int
ID)        giver bytearray med en kopi af data fra den givne post</P>
<P CLASS="klasseoversigt---kompakt-western">void setRecord(int ID,
byte[] nyedata, int afs, int lgd) s&aelig;tter dataene i den givne
post</P>
<P CLASS="klasseoversigt---kompakt-western">void
addRecordListener(RecordListener)  tilf&oslash;jer et objekt, der
lytter efter &aelig;ndringer i 'filen'</P>
<P CLASS="klasseoversigt---kompakt-western">void
removeRecordListener(RecordListener) fjerner et lytter-objekt</P>
<P CLASS="klasseoversigt---kompakt-western">RecordEnumeration
enumerateRecords(RecordFilter filter, RecordComparator, boolean
synkron)</P>
<P CLASS="klasseoversigt---kompakt-western">void
closeRecordStore()        lukker 'filen'</P>
<H2 CLASS="western" STYLE="">13.8 <a name='afsn13.8'></a>Udviklingsv&aelig;rkt&oslash;jer
til midletter</SPAN></H2>
<H3 CLASS="western">13.8.1 <a name='afsn13.8.1'></a>Wireless Toolkit</H3>
<P CLASS="western">Sun har udgivet en referenceimplementation af,
hvordan midletter skal fungere i forskellige mobiltelefoner og
h&aring;ndholdte apparater. Denne implementation hedder J2ME Wireless
Toolkit og k&oslash;rer under Windows, Linux og Sun Solaris. 
</P>
<P CLASS="western"><SPAN LANG="da-DK">Den kan hentes p&aring;
</SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://java.sun.com/products/j2mewtoolkit"><SPAN LANG="da-DK">http://java.sun.com/products/j2mewtoolkit</SPAN></A></SPAN><SPAN LANG="da-DK">.
</SPAN>
</P>
<P CLASS="western">Den best&aring;r af et v&aelig;rkt&oslash;j, hvor
man kan overs&aelig;tte og k&oslash;re sine midletter. 
</P>
<P CLASS="western"><IMG SRC="bog14_html_m6a82a7.png" NAME="Grafik42" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Det er ikke noget integreret udviklingsmilj&oslash;,
s&aring; faciliteter som integreret redigering, fejlfinding og
dokumentation m&aring; man undv&aelig;re.</P>
<P CLASS="western">Med Wireless Toolkit f&oslash;lger en r&aelig;kke
sm&aring; eksempelprogrammer. Eksemplerne er uvurderlige til at f&aring;
en fornemmelse af, hvordan de forskellige klasser benyttes, og
hvordan de grafiske komponenter ser ud i forskellige telefoner og
apparater.</P>
<P CLASS="western">N&aring;r man k&oslash;rer et eksempel, dukker en
emulator op med et billede af den p&aring;g&aelig;ldende telefon. Man
kan navigere enten ved at klikke p&aring; telefonens knapper eller
med piletasterne, F1, F2, Home og End (ESC afslutter emulatoren).</P>
<H3 CLASS="western">13.8.2 <a name='afsn13.8.2'></a>Sun ONE Studio Mobile Edition</H3>
<P CLASS="western">&quot;Sun ONE Studio, Mobile Edition&quot;, der
inkluderer Wireless Toolkit, er et integreret udviklingsmilj&oslash;,
der direkte er beregnet til udvikling af midletter. 
</P>
<P CLASS="western"><IMG SRC="bog14_html_m3423b5f0.png" NAME="Grafik10" ALIGN=BOTTOM BORDER=0><SPAN LANG="da-DK">Det
er relativt nemt at installere, k&oslash;rer under Windows, Linux og
Sun Solaris og kan hentes gratis p&aring; adressen: 
</SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://wwws.sun.com/software/sundev/jde"><SPAN LANG="da-DK">http://wwws.sun.com/software/sundev/jde</SPAN></A></SPAN><SPAN LANG="da-DK">.</SPAN></P>
<P CLASS="western">N&aring;r udviklingsmilj&oslash;et startes, dukker
en r&aelig;kke eksempler p&aring; midletter op, parat til at k&oslash;re
og med kildetekst, s&aring; man kan se hvordan forskellige ting
programmeres. H&oslash;jreklik f.eks. p&aring; den, der hedder
'UIDemo', og v&aelig;lg 'Execute' (som vist p&aring; figuren
ovenfor), og en telefon dukker op med midletten k&oslash;rende inden
i.</P>
<P CLASS="western">N&aring;r du vil lave dine egne midletter, skal du
huske at have dem med i en &quot;MIDlet suite&quot;, der ogs&aring;
skal kende alle supplerende klasser.</P>
<H3 CLASS="western">13.8.3 <a name='afsn13.8.3'></a>Borland JBuilder MobileSet</H3>
<P CLASS="western">Et andet udviklingsv&aelig;rkt&oslash;j til
midletter er JBuilder MobileSet. Det kan, som navnet antyder,
integreres med JBuilder. JBuilder MobileSet inkluderer Wireless
Toolkit.</P>
<P CLASS="western">Efter installationen har man alle de
funktionaliteter, som er kendt fra JBuilder. Man kan umiddelbart
overs&aelig;tte og k&oslash;re sine midletter.</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog14_html_1bd52584.png" NAME="Grafik18" ALIGN=BOTTOM BORDER=0></P>
<P CLASS="western">Sammen med JBuilder MobileSet ligger ogs&aring; en
pdf-fil, som bl. a. giver en n&aelig;rmere beskrivelse af, hvordan
installationen foreg&aring;r. Husk, at du skal ind og &aelig;ndre i
stien til JDK'et til der, hvor du har Wireless Toolkit liggende, for
at f&aring; lov til at lave en midlet.</P>
<P CLASS="western">N&aring;r du s&aring; skal til at k&oslash;re dine
almindelige programmer igen, skal du s&aelig;tte stien tilbage til
dit almindelige JDK (gratisudgaven af JBuilder tillader kun &eacute;t
JDK, s&aring; her er man n&oslash;dt til at erstatte det almindelige
JDK med J2MEs JDK).</P>
<H2 CLASS="western" STYLE="">13.9 <a name='afsn13.9'></a>Opbygningen
af J2ME</SPAN></H2>
<P CLASS="western">J2ME best&aring;r af en lagdelt struktur. Det
betyder, at leverand&oslash;ren af et indlejret system kan v&aelig;lge
den virtuelle maskine og de klasser, der skal v&aelig;re til r&aring;dighed
for programm&oslash;ren af en given slags apparat (f.eks. en
vaskemaskine eller et fjernsyn), og stadig bruge mindst mulig
hukommelse.</P>
<P CLASS="western">P&aring; figuren nedenfor er vist opbygningen af
J2ME:</P>
<P CLASS="western" ALIGN=CENTER><IMG SRC="bog14_html_1b2d1fff.gif"></P>
<P CLASS="western">Oven p&aring; styresystemet haves en virtuel
maskine af valgfri st&oslash;rrelse og en konfiguration med et udvalg
af klasser fra standardbiblioteket. Oven p&aring; dette haves en
profil, der afh&aelig;nger af, hvilken type apparat man har med at
g&oslash;re.</P>
<P CLASS="western">Den udgave af J2ME, der har afgjort st&oslash;rst
interesse og udbredelse, er den, der kan k&oslash;re i nyere
mobiltelefoner. Dens konfiguration kaldes CLDC (Connected Limited
Device Configuration) og har en profil der hedder MIDP (MIDlet
Profile). Det er den vi har besk&aelig;ftiget os med i dette kapitel.</P>
<P CLASS="western">En af id&eacute;erne i J2ME er, som med J2SE
(normal Java) og J2EE (Java til serversystemer), at give mulighed for
platformsuafh&aelig;ngighed, og programmer skrevet til MIDP-profilen
p&aring; CLDC-konfigurationen k&oslash;rer da ogs&aring; umodificeret
p&aring; mange mobiltelefoner og en lang r&aelig;kke andre lignende
apparater.</P>
<H3 CLASS="western">13.9.1 <a name='afsn13.9.1'></a>Konfigurationer</H3>
<P CLASS="western">En J2ME-konfiguration bestemmer den minimale
platform for en bestemt kategori af apparater. Konfigurationen best&aring;r
af en virtuel maskine, et minimalt s&aelig;t af biblioteker, klasser
og API'er (Application Programming Interface). 
</P>
<P CLASS="western">Der findes i &oslash;jeblikket 2 konfigurationer
af J2ME: 
</P>
<UL>
  <LI><P CLASS="western">Connected Limited Device Configuration (CLDC)
  - til apparater med 60 - 512 Kb hukommelse.</P>
  <LI><P CLASS="western">Connected Device Configuration (CDC) - til
  apparater med 512Kb - 2Mb hukommelse.</P>
</UL>
<P CLASS="western">CDLC benytter sig af en virtuel maskine, der
hedder KVM. KVM kan k&oslash;res af sm&aring; apparater, der er
beregnet til at v&aelig;re koblet p&aring; et netv&aelig;rk som
f.eks. mobiltelefoner og sm&aring; PDA'er.</P>
<P CLASS="western">CDC benytter den almindelige JVM eller evt. CVM
(en virtuel maskine i mellemst&oslash;rrelse) og er beregnet til
st&oslash;rre PDA'er, der f.eks. kan lave ruteplanl&aelig;gning eller
lignende.</P>

<H3 CLASS="western">13.9.2 <a name='afsn13.9.2'></a>Profiler</H3>
<P CLASS="western">En profil er en slags overbygning p&aring;
konfigurationen, og den giver mulighed for, at man kan tilpasse
udviklingsmilj&oslash;et til en bestemt type apparater. F.eks. findes
der 'Handheld profile' og 'MID profile' (til midletter).</P>
<P CLASS="western">Profilen indeholder yderligere klasser og metoder,
som man skal bruge for at udvikle til en bestemt slags apparater.
Derudover indeholder profilen oplysninger om konfigurationen af
J2ME-platformen.</P>
<P CLASS="western">Det betyder, at hver producent kan v&aelig;lge at
lave sin egen profil til en given slags apparat, som man kan bruge
til at lave programmer, der udnytter netop denne slags apparaters
specielle muligheder.</P>

<H2 CLASS="western">13.10 <a name='afsn13.10'></a>Yderligere l&aelig;sning</SPAN></H2>
<P CLASS="western">For yderligere information om J2ME og midletter
end den, der er givet her, henvises til:</P>
<UL>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Dokumentationen til
  Wireless Toolkit, der kan l&aelig;ses p&aring;:<BR>
  </SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://wireless.java.sun.com/"><SPAN LANG="da-DK">http://wireless.java.sun.com</SPAN></A></SPAN><SPAN LANG="da-DK">.
  <BR>Her kan du ogs&aring; hente den nyeste udgave af Wireless
  Toolkit.</SPAN></P>
  <LI><P CLASS="western"><SPAN LANG="da-DK">Hvis du er mere
  interesseret i, hvordan man bruger CDC, s&aring; kig p&aring;:<BR>
  </SPAN><SPAN STYLE="font-weight: medium"><A CLASS="western" HREF="http://java.sun.com/products/cdc"><SPAN LANG="da-DK">http://java.sun.com/products/cdc</SPAN></A></SPAN><SPAN LANG="da-DK">.</SPAN></P>
</UL>



<a href='http://javabog.dk/'>javabog.dk</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel12.jsp'>&lt;&lt; forrige</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='indhold.jsp'>indhold</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kapitel14.jsp'>n&aelig;ste &gt;&gt;</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='kode/'>programeksempler</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href='../index_VP.html'>om bogen</a>
<hr>
<font size=-2>http://javabog.dk/ - <b></b> af Jacob Nordfalk.
<br>
  Licens og kopiering under <a href='http://www.linuxbog.dk/licens.html'>&Aring;ben Dokumentlicens</a> (&Aring;DL)
  hvor intet andet er nævnt (71% af værket).
</font>
<br>
Ønsker du at se de sidste 29% af dette værk (362838 tegn)
skal du købe bogen. Så får du pæne figurer og layout, stikordsregister og en trykt bog med i købet.
<!-- netlæser: Wget/1.10, autoHent: true  -->
     

</body>
</html>
