03-28-2009 12:49 PM - last edited on 03-28-2009 01:30 PM
Hello,
today I used the gaugefield with a "bit" larger maxValue and my surprisewas to see negative perentage values % at a certain time...
The reason is quite simple - it looks like the API impl is using the following code to calculate the percentage value:
//currentValue is an int
//maxValue is also an int
int perentageValue = (currentValue*100)/maxValue
when you are coming to Integer.MAX_VALUE / 100 the code above will generate negative values - actually I could reprovude the behaviour by using the LABEL_AS_PROGRESS style and calculate and set the label with the algorithm above.
To fix the Problem you have to calculate the current percentage value like this:
int perentageValue = new Double(((double) currentValue*100) / maxValue).intValue()
myGaugeField.setLabel(perentageValue +"%");
that will give you always the correct percentage value even if you reacch Integer.MAX_VALUE value...
I hope this will be fixed in RIM's API...
Matthias
net.rim.device.api.ui.component.GaugeField
04-02-2009 11:11 AM
04-09-2009 06:52 AM
Hi,
I am sorry for the late reply - but I was on a bussines trip.
I am testing with OS 4.7.0.75 - but I could reproduce this also on Bold Sim (4.6.0.92) and also on a 8820 Device Sim (4.5.0.55)...The default Percentage Display inside the Progress Bar becomes Negative(in the sample code below at 24% - so it's 0%... up to 24%, go to -24% go to 0, to to 24% again...
Please find attached the code of my simple quick & dirty sample Application
import net.rim.device.api.system.ApplicationDescriptor; import net.rim.device.api.system.ApplicationManager; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.GaugeField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.SeparatorField; import net.rim.device.api.ui.container.MainScreen; public class BBGauge extends UiApplication { public static void main(String[] args) { new BBGauge().enterEventDispatcher(); } private BBGauge() { BBGaugeScreen screen = new BBGaugeScreen(); pushScreen(screen); } private class BBGaugeScreen extends MainScreen { private GaugeField pBar01; private GaugeField pBar02; private GaugeField pBar03; private GaugeField pBar04; public BBGaugeScreen(){ String _osversion = ""; ApplicationDescriptor[] ad = ApplicationManager. getApplicationManager().getVisibleApplications(); for (int i = 0; i < ad.length; i++) { if (ad[i].getModuleName().trim().equalsIgnoreCase( "net_rim_bb_ribbon_app")) { _osversion = ad[i].getVersion(); break; } } setTitle(_osversion); // specify at which percentage value the negative values will appear // in the default progress display (value have to be smaller then // 100... final int WHEN_NEG_SHOULD_APPEAR = 25; add(new LabelField("Broken (none % value at all):")); add(pBar01 = new GaugeField()); pBar01.reset("", 1, Integer.MAX_VALUE, 1); add(new SeparatorField()); add(new LabelField("Broken (negative percentage):")); add(pBar02 = new GaugeField()); pBar02.reset("", 1, Integer.MAX_VALUE/WHEN_NEG_SHOULD_APPEAR, 1); add(new SeparatorField()); // JUST as comparison two Gauges with own percentage // calculation (LABEL_AS_PROGRESS) add(new LabelField("Working (with own % calc):")); add(pBar03 = new GaugeField("", 1, Integer.MAX_VALUE, 1, GaugeField.LABEL_AS_PROGRESS)); pBar03.reset("", 1, Integer.MAX_VALUE, 1); add(new SeparatorField()); add(new LabelField("Broken (with default|wrong % calc):")); add(pBar04 = new GaugeField("", 1, Integer.MAX_VALUE/50, 1, GaugeField.LABEL_AS_PROGRESS)); pBar04.reset("", 1, Integer.MAX_VALUE/WHEN_NEG_SHOULD_APPEAR, 1); Thread worker = new Thread(){ public void run(){ for (int i=250000; i<Integer.MAX_VALUE; i=i+250000){ if(i<0 || i>Integer.MAX_VALUE){ i = Integer.MAX_VALUE; } int j = (int)i/WHEN_NEG_SHOULD_APPEAR; pBar01.setValue(i); pBar02.setValue(j); int p = new Double(((double)i*100)/pBar03.getValueMax()).intVa
lue(); pBar03.setLabel(p+"%"); pBar03.setValue(i); // this 'j*100' will generate a overflow in the INT // and that is causing the negative % value pBar04.setLabel(((j*100)/pBar04.getValueMax())+"%" ); pBar04.setValue(j); } } }; worker.start(); } } }
IMHO it's so obvious, that the calc of the default percentage value have a overflow problem - but of course I could be wrong.
Kind Regards
Matthias
04-09-2009 07:03 AM
The following piece of code is giving negative value.
((j*100)/pBar04.getValueMax())
04-09-2009 07:14 AM - last edited on 04-09-2009 07:23 AM
Just some additional explaiantions about the sample App...
bar01:
A default GaugeField where the Max value is just set to Integer.MAX_VALUE - for some reason this bar have the effect, that the percentage value is not increasing at all - it always be 0% [except in the moment when setValue(Integer.MAX_VALUE) will be called - then it's jumping to 100%]
bar02:
also a default GaugeField, here the MaxValue is set to Integer.MAX_VALUE/25 (actuall I put the "25" into a constant to make it easy for you to play arround a bit with the bars - the value in "WHEN_NEG_SHOULD_APPEAR" will specify the momentin which the percentage value will turn negative
bar03:
"My" only correct working Progress bar - here the LABEL_AS_PROGRESS will be used and the percentage value will be calculated as a double
bar04:
only for camparsing reasons - here I use also the LABEL_AS_PROGRESS but calculate the perentage value in a way how I personally assume it's done by the default GaugeField implementation internaly (unfortunatly there are no Sources available to check this myself)...
In the worker Thread:
for (int i=250000; i<Integer.MAX_VALUE; i=i+250000){
just to speed up the progressbar "a bit" I used not i++ in the for
cause of this I could get larger then Integer.MAX_VALUE - that's why the following code is there:
if(i<0 || i>Integer.MAX_VALUE){
i = Integer.MAX_VALUE;
}
Then for the ProgressBars that have set the MAX_VALUE to quotient of Integer.MAX_VALUE we have to adjust also the value of I [deviding I with the same value as we have devided the Integer.MAX_VALUE (in my current example this is 25 or better the value of WHEN_NEG_SHOULD_APPEAR)]
Then we set the Progress for bar01 (causing always percentage value"0%" ) and the Progress of bar02 - will cause -24 % at the moment we reach 25%...
the code is followed by the calculations of the lables for bar03 (IMHO correct implementation) and the bar04 - where you see, tha:
((j*100)/pBar04.getValueMax())+"%"
j*100 will cause the integer to "overflow" - and with that the percentage value becomes negative.
04-09-2009 07:16 AM - last edited on 04-09-2009 07:18 AM
Yes BBDeveloper - of course this line cause the overflow.
The "bug" I am try to reporting is, that the default GaugeField (like bar02) (when you do not use LABEL_AS_PROGRESS) will have exactly the same overflow problem as I would like to demonstrate with bar04.
04-14-2009 09:47 AM
04-18-2009 10:52 AM
04-27-2009 03:58 PM
04-27-2009 04:03 PM