/ Forside / Teknologi / Udvikling / Java / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Java
#NavnPoint
molokyle 3688
Klaudi 855
strarup 740
Forvirret 660
gøgeungen 500
Teil 373
Stouenberg 360
vnc 360
pmbruun 341
10  mccracken 320
J2ME -- List og Font
Fra : Thomas Jensen


Dato : 30-09-11 08:08

Jeg har lavet et j2me-program til min telefon, og fik nogle problemer da
jeg ville ændre skŕiftstørrelsen. Efter at have rodet med det et stykke
tid, finder jeg ud af - kort fortalt - at hvis jeg har en liste med 4
elementer, og ændrer fontstørrelsen på dem, og derefter tlføjer et 5.
element, så opstår der er en ArrayIndexOutOfBoundsException. Hvis jeg
ikke ændrer fontstørrelsen, så er der ingen problemer i at tilføje flere
elementer til listen.

Jeg har inkluderet et lille program der demonstrerer problemet, længere
nede i teksten. Vær opmærksom på, at det er j2me kode. setFont er en
metode til List - se

http://java.sun.com/javame/reference/apis/jsr118/javax/microedition/lcdui/
List.html

Nu er jeg jo bare en amatør, med et meget begrænset kendskab til java,
men jeg synes det ligner en bug. Gør jeg noget indlysende forkert? Er der
nogen der har et forslag til hvordan jeg kan løse problemet?


Hvis jeg kører test-programmet i Netbeans6.9 med WTK2.5.2 og JDK1.6.0.26
under Linux, får jeg følgende output:

java.lang.ArrayIndexOutOfBoundsException at
javax.microedition.lcdui.ChoiceGroup.insertImpl(ChoiceGroup.java:1420) at
javax.microedition.lcdui.ChoiceGroup.append(ChoiceGroup.java:397) at
javax.microedition.lcdui.List.append(List.java:429) at
listtest.commandAction(listtest.java:70) at
javax.microedition.lcdui.Display$DisplayAccessor.commandAction
(Display.java:2093)
at javax.microedition.lcdui.Display$DisplayManagerImpl.commandAction
(Display.java:2929)
at com.sun.midp.lcdui.DefaultEventHandler.commandEvent
(DefaultEventHandler.java:297)
at com.sun.midp.lcdui.AutomatedEventHandler.commandEvent
(AutomatedEventHandler.java:667)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.handleVmEvent
(DefaultEventHandler.java:711)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.run
(DefaultEventHandler.java:608)

Hvis jeg bygger og kører med ktoolbar i WTK2.5.2, får jeg:

java.lang.ArrayIndexOutOfBoundsException at
javax.microedition.lcdui.ChoiceGroup.insertImpl(+456) at
javax.microedition.lcdui.ChoiceGroup.append(+25) at
javax.microedition.lcdui.List.append(+9) at listtest.commandAction(+71)
at javax.microedition.lcdui.Display$DisplayAccessor.commandAction(+282) at
javax.microedition.lcdui.Display$DisplayManagerImpl.commandAction(+10) at
com.sun.midp.lcdui.DefaultEventHandler.commandEvent(+68) at
com.sun.midp.lcdui.AutomatedEventHandler.commandEvent(+47) at
com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.handleVmEvent
(+186)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.run(+57)

Altså cirka det samme. Når jeg kører programmet på min Samsung B2100
telefon får jeg ingen errors, men den nye linie (list.append("test",
null)) bliver ikke tilføjet, og de efterfølgende list.setFont(i, f)
bliver ikke udført.

Okay, gode råd modtages...



-- CODE START --

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

public class listtest extends MIDlet implements CommandListener {
private Display display;
private List list;
private Command exitcmd, reloadcmd;
private Vector v;
Font f;

public void startApp() {

reloadcmd = new Command("Reload", Command.SCREEN, 1);
exitcmd = new Command("Exit", Command.EXIT, 2);

f = Font.getFont(0, 0, Font.SIZE_LARGE);

v = new Vector(1,1);
v.addElement("string1");
v.addElement("string2");
v.addElement("string3");
v.addElement("string4");

list = new List("", Choice.IMPLICIT);
list.addCommand(reloadcmd);
list.addCommand(exitcmd);
list.setCommandListener(this);

int i = 0;
for (Enumeration e = v.elements();
e.hasMoreElements(); i++ ) {
list.append((String)e.nextElement(), null);
// ArrayIndexOutOfBoundsException, if setting font here...
// list.setFont(i, f);
}

for (i=1 ; i<list.size() ; i++ ) { // not on first element
// It's okay here
list.setFont(i, f);
}

display = Display.getDisplay(this);
display.setCurrent(list);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) { }

public void commandAction (Command c, Displayable d) {
if (c == reloadcmd) {

// list.deleteAll();
// for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
// list.append((String)e.nextElement(), null);
// }

list.append("test", null);

// for (i=0 ; i<list.size() ; i++ ) {
// if (!list.getFont(i).equals(f)) {
// list.setFont(i, f);
// }
// }

display.setCurrent(list);
}

if (c == exitcmd) {
destroyApp(true);
notifyDestroyed();
}
}
}

-- CODE END --




--
Thomas Jensen, Denmark




--
Thomas Jensen, Denmark

 
 
Thomas Jensen (30-09-2011)
Kommentar
Fra : Thomas Jensen


Dato : 30-09-11 08:31

On Fri, 30 Sep 2011 07:07:41 +0000, Thomas Jensen wrote:

Jeg ved ikke hvad der går galt med de her linieskift - prøver lige igen

Hvis jeg kører test-programmet i Netbeans6.9 med WTK2.5.2 og JDK1.6.0.26
under Linux, får jeg følgende output:

java.lang.ArrayIndexOutOfBoundsException
at javax.microedition.lcdui.ChoiceGroup.insertImpl(ChoiceGroup.java:1420)
at javax.microedition.lcdui.ChoiceGroup.append(ChoiceGroup.java:397)
at javax.microedition.lcdui.List.append(List.java:429)
at listtest.commandAction(listtest.java:70)
at javax.microedition.lcdui.Display$DisplayAccessor.commandAction
(Display.java:2093)
at javax.microedition.lcdui.Display$DisplayManagerImpl.commandAction
(Display.java:2929)
at com.sun.midp.lcdui.DefaultEventHandler.commandEvent
(DefaultEventHandler.java:297)
at com.sun.midp.lcdui.AutomatedEventHandler.commandEvent
(AutomatedEventHandler.java:667)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.handleVmEvent
(DefaultEventHandler.java:711)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.run
(DefaultEventHandler.java:608)

Hvis jeg bygger og kører med ktoolbar i WTK2.5.2, får jeg:

java.lang.ArrayIndexOutOfBoundsException
at javax.microedition.lcdui.ChoiceGroup.insertImpl(+456)
at javax.microedition.lcdui.ChoiceGroup.append(+25)
at javax.microedition.lcdui.List.append(+9) at listtest.commandAction(+71)
at javax.microedition.lcdui.Display$DisplayAccessor.commandAction(+282)
at javax.microedition.lcdui.Display$DisplayManagerImpl.commandAction(+10)
at com.sun.midp.lcdui.DefaultEventHandler.commandEvent(+68)
at com.sun.midp.lcdui.AutomatedEventHandler.commandEvent(+47)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.handleVmEvent
(+186)
at com.sun.midp.lcdui.DefaultEventHandler$QueuedEventHandler.run(+57)



-- CODE START --

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

public class listtest extends MIDlet implements CommandListener {
private Display display;
private List list;
private Command exitcmd, reloadcmd;
private Vector v;
Font f;

public void startApp() {

reloadcmd = new Command("Reload", Command.SCREEN, 1);
exitcmd = new Command("Exit", Command.EXIT, 2);

f = Font.getFont(0, 0, Font.SIZE_LARGE);

v = new Vector(1,1);
v.addElement("string1");
v.addElement("string2");
v.addElement("string3");
v.addElement("string4");

list = new List("", Choice.IMPLICIT);
list.addCommand(reloadcmd);
list.addCommand(exitcmd);
list.setCommandListener(this);

int i = 0;
for (Enumeration e = v.elements(); e.hasMoreElements(); i++ ) {
list.append((String)e.nextElement(), null);
// ArrayIndexOutOfBoundsException, if setting font here...
// list.setFont(i, f);
}

for (i=1 ; i<list.size() ; i++ ) { // not on first element
// It's okay here
list.setFont(i, f);
}

display = Display.getDisplay(this);
display.setCurrent(list);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) { }

public void commandAction (Command c, Displayable d) {
if (c == reloadcmd) {

// list.deleteAll();
// for (Enumeration e = v.elements(); e.hasMoreElements(); ) {
// list.append((String)e.nextElement(), null);
// }

list.append("test", null);

// for (i=0 ; i<list.size() ; i++ ) {
// if (!list.getFont(i).equals(f)) {
// list.setFont(i, f);
// }
// }

display.setCurrent(list);
}

if (c == exitcmd) {
destroyApp(true);
notifyDestroyed();
}
}
}

-- CODE END --


--
Thomas Jensen, Denmark

Arne Vajhøj (01-10-2011)
Kommentar
Fra : Arne Vajhøj


Dato : 01-10-11 01:09

On 9/30/2011 3:30 AM, Thomas Jensen wrote:
> Hvis jeg kører test-programmet i Netbeans6.9 med WTK2.5.2 og JDK1.6.0.26
> under Linux, får jeg følgende output:
>
> java.lang.ArrayIndexOutOfBoundsException
> at javax.microedition.lcdui.ChoiceGroup.insertImpl(ChoiceGroup.java:1420)

> Hvis jeg bygger og kører med ktoolbar i WTK2.5.2, får jeg:
>
> java.lang.ArrayIndexOutOfBoundsException
> at javax.microedition.lcdui.ChoiceGroup.insertImpl(+456)

> f = Font.getFont(0, 0, Font.SIZE_LARGE);
>
> v = new Vector(1,1);
> v.addElement("string1");
> v.addElement("string2");
> v.addElement("string3");
> v.addElement("string4");
>
> list = new List("", Choice.IMPLICIT);
> list.addCommand(reloadcmd);
> list.addCommand(exitcmd);
> list.setCommandListener(this);
>
> int i = 0;
> for (Enumeration e = v.elements(); e.hasMoreElements(); i++ ) {
> list.append((String)e.nextElement(), null);
> // ArrayIndexOutOfBoundsException, if setting font here...
> // list.setFont(i, f);
> }
>
> for (i=1 ; i<list.size() ; i++ ) { // not on first element
> // It's okay here
> list.setFont(i, f);
> }

Nu kender jeg intet til ME, så jeg kan sagtens over se noget,
men umiddlbart virker det mystisk.

Kan du finde ud af hvilken værdi af i der giver exception
of hvad list.size() er når det sker?

Arne


Thomas Jensen (30-09-2011)
Kommentar
Fra : Thomas Jensen


Dato : 30-09-11 08:34

On Fri, 30 Sep 2011 07:30:40 +0000, Thomas Jensen wrote:
> On Fri, 30 Sep 2011 07:07:41 +0000, Thomas Jensen wrote:
>
> Jeg ved ikke hvad der går galt med de her linieskift - prøver lige igen
>

Nå. Det plejer da ikke at være et problem... Det beklager jeg.


--
Thomas Jensen, Denmark

Thomas Jensen (01-10-2011)
Kommentar
Fra : Thomas Jensen


Dato : 01-10-11 14:00

On Fri, 30 Sep 2011 20:08:57 -0400, Arne Vajhøj wrote:

> Kan du finde ud af hvilken værdi af i der giver exception of hvad
> list.size() er når det sker?
>
>

Ja, jeg ved godt det forvirrer lidt med de der loops og 'i' der bliver
sat til 1 osv. Men det er ikke her problemet er.

Jeg er lige blevet lidt klogere.

Det viser sig, at når en liste oprettes, så allokeres der plads til 4
elementer (et array). Hvis et 5. element tilføjes (list.append()), så
allokeres der plads til 4 nye elementer. numOfEls er nu 5, men der er
allokeret plads til 8 elementer. At det foregår i spring af 4 er ikke det
vigtige i denne sammenhæng, men derimod at numOfEls indeholder det reelle
antal elementer i listen. SÃ¥ det er ikke her problemet er.

I debuggeren bliver 'fontEls' ikke sat, før første kald til setFont().
fontEls er et array af Font-objekter i List, og størrelsen af det array
bliver sat til det aktuelle antal elementer i listen - på det tidspunkt
hvor første kald til setFont() foretages.

   int i = 0;
   for (Enumeration e = v.elements(); e.hasMoreElements(); i++ ) {
      list.append((String)e.nextElement(), null);
      // ArrayIndexOutOfBoundsException, if setting font here...
      //list.setFont(i, f);
   }

Dvs, hvis jeg fjerner kommentaren, så numOfEls 1 efter første gennemløb,
og fontEls indeholder et font-oject. Når andet gennemløb begynder, vil
list.append(), af uvisse årsager, udløse en exception. Hvis list.setFont
() ikke køres i ovenstående loop, så vil numOfEls være 4 (list.size())
når vi når til næste loop:

   for (i=0 ; i<list.size() ; i++ ) {
      // It's okay here
      list.setFont(i, f);
   }

og der er ingen problemer, før vi bruger list.append() igen.

Det kan undre at list.append() smider en exception. Jeg kunne forstå det,
hvis det var fontEls der ikke blev opdateret, og derfor smed en exception
når man prøvede at skrive til et index der ikke fandtes. Men det er
list.append() der udløser en exception.

En List er: public class List extends Screen implements Choice

Om Choice står der:

"Each element of a Choice is composed of a text string part, an Image
part, and a font attribute that are all treated as a unit. "

Jeg synes nu ikke det ligner "a unit". fontEls bliver ikke allokeret før
man bruger setFont() første gang, og er ikke en del af et element, men en
del af en listen.

"When a new element is inserted or appended, the implementation provides
a default font for the font attribute. This default font is the same font
that is used if the application calls setFont(i, null). "

Men så langt når man ikke, for fontEls når ikke at blive opdateret med
oplysningen om at listen er blevet udviddet.

Jeg tror løsningen bliver at slette listen, og så oprette en ny, hver
gang jeg har behov for at tilføje nye elementer til listen. Det lyder
grimt, men i praksis tager det et splitsekund, så det er nok det bedste.



--
Thomas Jensen, Denmark

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408914
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste