Setting Autocompletefield rowheight - blackberry

I am using drawListRow to repaint the autocomplete field, but I'm having trouble to set it's field height, here is my code:
autoCustomer = new AutoCompleteField(custList, style){
public void drawListRow(ListField clistField, Graphics g,
int index, int y, int width) {
BasicFilteredListResult result = (BasicFilteredListResult)
autoCustomer.get(clistField, index);//);
if (result == null)
return;
String[] stringArray = parseMessage(result._object.toString(), Font.getDefault().derive(Font.PLAIN),fontSize, width-30);
int i;
int yCoord = 0;
int xCoord = 0;
//int rowHeight = (stringArray.length * fontHeight)+3;
clistField.setRowHeight((stringArray.length * fontHeight)+3); //already did this, but it won't work
System.out.println(stringArray.length);
g.setFont( Font.getDefault().derive(Font.PLAIN,fontSize,Ui.UNITS_px));
for(i = 0;i<stringArray.length;i++){
yCoord = y + (fontHeight*(i));
if(i>0)
xCoord = 20;
g.drawText(stringArray[i].trim() , xCoord, yCoord, (DrawStyle.LEFT | DrawStyle.ELLIPSIS | DrawStyle.TOP ), width-20);
}
}
What should I do to make proper row height with this autocomplete ?

I unintentionally found the answer, the first argument is index of the list and the second is the height.
The documentation doesn't mention about this, I only found setRowHeight(int arg0, int arg1) in the documentation of class in eclipse.
The solution is simple
clistField.setRowHeight(index,(stringArray.length * fontHeight)+3);

Related

Libgdx Pixmap Memory Leak

I am codeing a little project where i need a Line from a given Object to my Mouse. I made things work and came up with this quick and dirty code:
addListener(new ClickListener() {
Image lineImage;
Pixmap pixmap;
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
// Get Actor Origin
// Get local Origin
int x2 = (int) event.getListenerActor().getX(Align.center);
int y2 = (int) event.getListenerActor().getY(Align.center);
// Make it global
x2 = (int) event.getListenerActor().getParent().getX() + x2;
y2 = (int) event.getListenerActor().getParent().getY() + y2;
// Get Stage Coordinates
Vector2 v = localToStageCoordinates(new Vector2(x, y));
Vector2 v2 = new Vector2(x2, y2);
Stage stage = event.getStage();
int width = (int) stage.getWidth();
int height = (int) stage.getHeight();
if (pixmap == null) {
pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
} else {
pixmap.setColor(1, 1, 1, 0);
pixmap.fill();
}
pixmap.setColor(Color.BLUE);
// line
for (int m = -2; m <= 2; m++) {// x
for (int n = -2; n <= 2; n++) {// y
pixmap.drawLine((int) (v2.x+m), (int) (height-v2.y+n) , (int) (v.x+m), (int) (height-v.y+n));
}
}
if (lineImage != null) {
/*lineImage.clear();
lineImage.remove();
*/
lineImage.setDrawable(new SpriteDrawable(new Sprite(new Texture(pixmap))));
} else {
lineImage = new Image(new Texture(pixmap));
}
lineImage.setPosition(0,0);
stage.addActor(lineImage);
// super.touchDragged(event, x, y, pointer);
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
if (lineImage != null) {
lineImage.clear();
lineImage.remove();
}
lineImage = null;
super.touchUp(event, x, y, pointer, button);
}
});
The Problem with this is, when i use this Listener on a Image and i activate touchdragged for about 20 seconds, there will be a memory leak.
I have no idea why this happens, i tried a lot of things but nothing seams to help me fix this. Do you have any ideas?
#noone is right. Add the line where is commented to dispose your pixmap after you assigned the drawable to the lineImage.
if (lineImage != null) {
/*lineImage.clear();
lineImage.remove();
*/
lineImage.setDrawable(new SpriteDrawable(new Sprite(new Texture(pixmap))));
} else {
lineImage = new Image(new Texture(pixmap));
}
pixmap.dispose(); // <-----------Add this line here!!!
lineImage.setPosition(0,0);
stage.addActor(lineImage);

Improve javaFx processing performance

I'm working on Image processing with javaFx. I think that my code is not enouth efficient (With HD images, refresh is very slow). Because I do a for on each pixel of my image everytime I have to refresh it. But I don't know how to do differently.
So I need help to improve the performance of my processing.
This is my code :
import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class Example extends Application {
private Image src;
private WritableImage dest;
private int width;
private int height;
int value = 0;
#Override
public void start(Stage stage) {
AnchorPane root = new AnchorPane();
initImage(root);
Scene scene = new Scene(root);
stage.setTitle("Demo processing");
stage.setResizable(false);
stage.setScene(scene);
stage.show();
}
private void initImage(AnchorPane root) {
src = new Image(
"http://mikecann.co.uk/wp-content/uploads/2009/12/ScreenHunter_02-Dec.-10-19.41-1024x484.jpg");
width = (int) src.getWidth();
height = (int) src.getHeight();
root.setPrefSize(800, 800 + 50);
ScrollPane scrollPane = new ScrollPane();
scrollPane.setPrefHeight(600);
scrollPane.setPrefWidth(1000);
dest = new WritableImage(width, height);
ImageView destView = new ImageView(dest);
scrollPane.setContent(destView);
root.getChildren().add(scrollPane);
AnchorPane.setTopAnchor(scrollPane, 0.0);
Slider slider = new Slider(0, 255, 1);
slider.setPrefSize(800, 50);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
slider.setSnapToTicks(true);
slider.setMajorTickUnit(1.0);
slider.setMinorTickCount(0);
slider.setLayoutY(700);
slider.valueProperty().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable o) {
value = (int) ((DoubleProperty) o).get();
color();
}
});
root.getChildren().add(slider);
color();
}
private void color() {
PixelReader reader = src.getPixelReader();
PixelWriter writer = dest.getPixelWriter();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Color color = reader.getColor(x, y);
double red = (double) value * x * y / (width * height) / 255;
double green = color.getGreen();
double blue = (double) value * ((width * height) - x * y)
/ (width * height) / 255;
writer.setColor(x, y, Color.color(red, green, blue));
}
}
}
public static void main(String[] args) {
launch(args);
}
}
And this is with a full HD image :
src = new Image(
"http://www.freedomwallpaper.com//nature-wallpaper-hd/hd_sunshine_hd.jpg");
Getitng color of each pixel in loop is too slow. So, get entire pixels first, and change colors, finally wirte changed colors with PixelWriter.
Like this
private void color() {
PixelReader reader = src.getPixelReader();
WritablePixelFormat<IntBuffer> format = WritablePixelFormat.getIntArgbInstance();
int[] pixels = new int[width * height]; // Buffer for all pixels
reader.getPixels(0, 0, width, height, format, pixels, 0, width); // get all pixels by argb format
int alpha = 0xFF << 24;
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int index = x + y * width;
int argb = pixels[index];
int red = value * x * y / (width * height);
int green = (argb >> 8) & 0xFF;
int blue = value * ((width * height) - x * y)
/ (width * height);
int newArgb = alpha | (red << 16) | (green << 8) | blue;
pixels[index] = newArgb;
}
}
PixelWriter writer = dest.getPixelWriter();
writer.setPixels(0, 0, width, height, format, pixels, 0, width); // write entire image
}

align label texts in horizontal field manager in Blackberry 5.0

I am adding multiple label fields in HFM, the text of which is coming from a String[]. Suppose there are 5 labels. I want the labels in Left, HCentre and Right of HFM. I m creating the labelfields like,
String[] labels = {------};
for( int i=0;labels.length;i++)
{
LabelField labelField = new LabelField(labels[i],Field.FOCUSABLE|Field.ACTION_INVOKE){
public void paint(Graphics g) {
-------
-------
}
protected void layout( int width, int height ){
super.layout(Display.getWidth()/3, getContentHeight());
setExtent(Display.getWidth()/3, getContentHeight());
//setPosition(Display.getWidth()/3,0);
};
HFM.add(labelField);
}
But it is not coming in the format I want.
How to do it? am I doing something wrong in Field's layout()? Please correct me if I am wrong.
I am attaching the screenshot of what I am getting now, but the alignment I want is 1st LabelField to the Left of HFM, 2nd at the Centre and 3rd at the Right of HFM, but only the thing is I am getting the LabelTexts from a String[].
According to your requirement , this Sample class will help you ..
import net.rim.device.api.ui.*;
public class JustifiedEvenlySpacedHorizontalFieldManager extends Manager
{
private static final int SYSTEM_STYLE_SHIFT = 32;
public JustifiedEvenlySpacedHorizontalFieldManager()
{
this( 0 );
}
public JustifiedEvenlySpacedHorizontalFieldManager( long style )
{
super( USE_ALL_WIDTH | style );
}
protected void sublayout( int width, int height )
{
int availableWidth = width;
int numFields = getFieldCount();
int maxPreferredWidth = 0;
int maxHeight = 0;
// There may be a few remaining pixels after dividing up the space
// we must split up the space between the first and last buttons
int fieldWidth = width / numFields;
int firstFieldExtra = 0;
int lastFieldExtra = 0;
int unUsedWidth = width - fieldWidth * numFields;
if( unUsedWidth > 0 ) {
firstFieldExtra = unUsedWidth / 2;
lastFieldExtra = unUsedWidth - firstFieldExtra;
}
int prevRightMargin = 0;
// Layout the child fields, and calculate the max height
for( int i = 0; i < numFields; i++ ) {
int nextLeftMargin = 0;
if( i < numFields - 1 ) {
Field nextField = getField( i );
nextLeftMargin = nextField.getMarginLeft();
}
Field currentField = getField( i );
int leftMargin = i == 0 ? currentField.getMarginLeft() : Math.max( prevRightMargin, currentField.getMarginLeft() ) / 2;
int rightMargin = i < numFields - 1 ? Math.max( nextLeftMargin, currentField.getMarginRight() ) / 2 : currentField.getMarginRight();
int currentVerticalMargins = currentField.getMarginTop() + currentField.getMarginBottom();
int currentHorizontalMargins = leftMargin + rightMargin;
int widthForButton = fieldWidth;
if( i == 0 ) {
widthForButton = fieldWidth + firstFieldExtra;
} else if( i == numFields -1 ) {
widthForButton = fieldWidth + lastFieldExtra;
}
layoutChild( currentField, widthForButton - currentHorizontalMargins, height - currentVerticalMargins );
maxHeight = Math.max( maxHeight, currentField.getHeight() + currentVerticalMargins );
prevRightMargin = rightMargin;
nextLeftMargin = 0;
}
// Now position the fields, respecting the Vertical style bits
int usedWidth = 0;
int y;
prevRightMargin = 0;
for( int i = 0; i < numFields; i++ ) {
Field currentField = getField( i );
int marginTop = currentField.getMarginTop();
int marginBottom = currentField.getMarginBottom();
int marginLeft = Math.max( currentField.getMarginLeft(), prevRightMargin );
int marginRight = currentField.getMarginRight();
switch( (int)( ( currentField.getStyle() & FIELD_VALIGN_MASK ) >> SYSTEM_STYLE_SHIFT ) ) {
case (int)( FIELD_BOTTOM >> SYSTEM_STYLE_SHIFT ):
y = maxHeight - currentField.getHeight() - currentField.getMarginBottom();
break;
case (int)( FIELD_VCENTER >> SYSTEM_STYLE_SHIFT ):
y = marginTop + ( maxHeight - marginTop - currentField.getHeight() - marginBottom ) >> 1;
break;
default:
y = marginTop;
}
setPositionChild( currentField, usedWidth + marginLeft, y );
usedWidth += currentField.getWidth() + marginLeft;
prevRightMargin = marginRight;
}
setExtent( width, maxHeight );
}
}
please have a look on this link :-
[http://supportforums.blackberry.com/t5/Java-Development/Implement-advanced-buttons-fields-and-managers/ta-p/488276][1]
you will get all kinds of Custom Components
Cheers ..!!!
[1]: http://supportforums.blackberry.com/t5/Java-Development/Implement-advanced-buttons-fields-and-managers/ta-p/488276

Using zxing in Blackberry 5.0

I'm stucked when implementing Barcode scanning in Blackberry 5.0 SDK, since I'm look into deep search on the internet, and found no clue.
Then I started to write my own class to provide Barcode Scanning (using zxing core)
then I need to implements BitmapLuminanceSource (rim version not Android version)
public class BitmapLuminanceSource extends LuminanceSource {
private final Bitmap bitmap;
public BitmapLuminanceSource(Bitmap bitmap){
super(bitmap.getWidth(),bitmap.getHeight());
this.bitmap = bitmap;
}
public byte[] getRow(int y, byte[] row) {
//how to implement this method
return null;
}
public byte[] getMatrix() {
//how to implement this method
return null;
}
}
Well, the javadoc in LuminanceSource tells you what it returns. And you have implementations like PlanarYUVLuminanceSource in android/ that show you an example of it in action. Did you look at these at all?
The quick answer though is that both return one row of the image, or the entire image, as an array of luminance values. There is one byte value per pixel and it should be treated as an unsigned value.
I've solved this problem.
Here's the BitmapLuminanceSource implementation
import net.rim.device.api.system.Bitmap;
import com.google.zxing.LuminanceSource;
public class BitmapLuminanceSource extends LuminanceSource {
private final Bitmap bitmap;
private byte[] matrix;
public BitmapLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
int width = bitmap.getWidth();
int height = bitmap.getHeight();
this.bitmap = bitmap;
int area = width * height;
matrix = new byte[area];
int[] rgb = new int[area];
bitmap.getARGB(rgb, 0, width, 0, 0, width, height);
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = rgb[offset + x];
int luminance = (306 * ((pixel >> 16) & 0xFF) + 601
* ((pixel >> 8) & 0xFF) + 117 * (pixel & 0xFF)) >> 10;
matrix[offset + x] = (byte) luminance;
}
}
rgb = null;
}
public byte[] getRow(int y, byte[] row) {
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException(
"Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
int offset = y * width;
System.arraycopy(this.matrix, offset, row, 0, width);
return row;
}
public byte[] getMatrix() {
return matrix;
}
}
I added com.google.zxing (library for Barcode encode/decode) to my project

how to change a color in an image programmatically?

I have a .PNG image with a transparent background and a drawing in it with a black color, how could I change the "black drawing color" in this image to any color i want programmatically; using rim 4.5 API ?
THANKS IN ADVANCE ....
I found the solution, here it is for those who are interested.
Bitmap colorImage(Bitmap image, int color) {
int[] rgbData= new int[image.getWidth() * image.getHeight()];
image.getARGB(rgbData,
0,
image.getWidth(),
0,
0,
image.getWidth(),
image.getHeight());
for (int i = 0; i < rgbData.length; i++) {
int alpha = 0xFF000000 & rgbData[i];
if((rgbData[i] & 0x00FFFFFF) == 0x00000000)
rgbData[i]= alpha | color;
}
image.setARGB(rgbData,
0,
image.getWidth(),
0,
0,
image.getWidth(),
image.getHeight());
return image;
}
You can parse the image RGBs searching for the black color and replace it with whatever color you desire.
You can read your PNG image to byte array and edit palette chunk.
This method is suitable only for PNG-8 images.
Here is my code:
public static Image createImage(String filename) throws Throwable
{
DataInputStream dis = null;
InputStream is = null;
try {
is = new Object().getClass().getResourceAsStream(filename);
dis = new DataInputStream(is);
int pngLength = dis.available();
byte[] png = new byte[pngLength];
int offset = 0;
dis.read(png, offset, 4); offset += 4; //‰PNG
dis.read(png, offset, 4); offset += 4; //....
while (true) {
//length
dis.read(png, offset, 4); offset += 4;
int length = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24);
//chunk type
dis.read(png, offset, 4); offset += 4;
int type = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24);
//chunk data
for (int i=0; i<length; i++) {
dis.read(png, offset, 1); offset += 1;
}
//CRC
dis.read(png, offset, 4); offset += 4;
int crc = (png[offset-1]&0xFF) | ((png[offset-2]&0xFF)<<8) | ((png[offset-3]&0xFF)<<16) | ((png[offset-4]&0xFF)<<24);
if (type == 0x504C5445) { //'PLTE'
int CRCStart = offset-4;
int PLTEStart = offset-4-length;
//modify PLTE chunk
for (int i=PLTEStart; i<PLTEStart+length; i+=3) {
png[i+0] = ...
png[i+1] = ...
png[i+2] = ...
}
int newCRC = crc(png, PLTEStart-4, length+4);
png[CRCStart+0] = (byte)(newCRC>>24);
png[CRCStart+1] = (byte)(newCRC>>16);
png[CRCStart+2] = (byte)(newCRC>>8);
png[CRCStart+3] = (byte)(newCRC);
}
if (offset >= pngLength)
break;
}
return Image.createImage(png, 0, pngLength);
} catch (Throwable e) {
throw e;
} finally {
MainCanvas.closeInputStream(dis);
MainCanvas.closeInputStream(is);
}
}

Resources