BeforeTextChanged event doesn't return the text about to be entered in custom Entry Renderer - xamarin

I've a custom Entry Renderer in Android and I've implemented BeforeTextChanged event so that I get the text which is gonna be entered, but it doesn't return that text.
I've implemented in two different ways:
First implementing ITextWatcher by the class and then overriding the mentioned event (helping this link):
void ITextWatcher.BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
var test1 = new string(s?.ToArray());
var test2 = Control?.Text;
SpannableString spannableString = new SpannableString(s);
BackgroundColorSpan backgroundSpan = new BackgroundColorSpan(Color.Blue);
spannableString.SetSpan(backgroundSpan, start, start + count,
SpanTypes.ExclusiveExclusive);
var test3 = spannableString;
}
Second way:
Control.BeforeTextChanged += (sender, args) =>
{
var test1 = new string(args?.Text.ToArray());
var entry = sender as EditText;
var test2 = entry?.Text;
var test3 = Control?.Text;
};
But none of them will return the text that is about to be entered.
What I want is to access that text and only in some circumstances allowing it to be inserted.
I don't wanna use Behavior as it doesn't suit my need.

First way, ITextWatcher:
class MyEntryRenderer : EntryRenderer
{
public MyEntryRenderer() : base()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.SetBackgroundColor(global::Android.Graphics.Color.LightGreen);
Control.AddTextChangedListener(new MyTextWatcher());
}
}
}
class MyTextWatcher :Java.Lang.Object, ITextWatcher
{
public void AfterTextChanged(IEditable s)
{
Android.Util.Log.Error("lv", "afterTextChanged ---->" + s);
}
public void BeforeTextChanged(ICharSequence s, int start, int count, int after)
{
Android.Util.Log.Error("lv", "beforeTextChanged ----> s=" + s + "----start=" + start
+ "----after=" + after + "----count" + count);
}
public void OnTextChanged(ICharSequence s, int start, int before, int count)
{
Android.Util.Log.Error("lv", "onTextChanged ---->s=" + s + "----start=" + start
+ "----before=" + before + "----count" + count);
}
}
it works well.
Second way, Control.BeforeTextChanged, it also works well.
it doesn't return that text
The methods you provided in your question, they are all work well in my phone. Please show more codes, so I can help you find where is wrong.

Related

Running Multiple threads in queue using BlockingCollections

My program has 3 functions. Each function takes a list of Items and fill certain information.
For example
class Item {
String sku,upc,competitorName;
double price;
}
function F1 takes a List and fills upc
function F2 takes List (output of F1) and fills price.
function F3 takes List (output of F2) and fills competitorName
F1 can process 5 items at a time,
F2 can process 20 items at a time,
F3 also 20.
Right now I am running F1 -> F2 -> F3 in serial because F2 needs info(UPC code) from F1. F3 needs price from F2.
I would like to make this process efficient by running F1 run continuously instead of waiting for F2 and F3 to be completed. F1 executes and output into queue then F2 takes 20 items at a time and process them. and then follows F3.
How can i achieve this by using BlockingCollection and Queue?
This is a typical use case of Apache Storm in case you've continuous items coming in to F1. You can implement this in Storm in matter of minutes and you'll have fast and perfectly parallel system in place. Your F1, F2 and F3 will become bolts and your Items producer will become spout.
Since you asked how to do it using BlockingCollections here is an implementation. You'll need 3 threads in total.
ItemsProducer: It is producing 5 items at a time and feeding it to F1.
F2ExecutorThread: It is consuming 20 items at a time and feeding it to F2.
F3ExecutorThread: It is consuming 20 items at a time and feeding it to F3.
You also have 2 blocking queues one is used to transfer data from F1->F2 and one from F2->F3. You can also have a queue to feed data to F1 in similar fashion if required. It depends upon how you are getting the items. I've used Thread.sleep to simulate the time required to execute the function.
Each function will keep looking for items in their assigned queue, irrespective of what other functions are doing and wait until the queue has items. Once they've processed the item they'll put it in another queue for another function. They'll wait until the other queue has space if it is full.
Since all your functions are running in different threads, F1 won't be waiting for F2 or F3 to finish. If your F2 and F3 are significantly faster then F1 you can assign more threads to F1 and keep pushing to same f2Queue.
public class App {
final BlockingQueue<Item> f2Queue = new ArrayBlockingQueue<>(100);
final BlockingQueue<Item> f3Queue = new ArrayBlockingQueue<>(100);
public static void main(String[] args) throws InterruptedException {
App app = new App();
app.start();
}
public void start() throws InterruptedException {
Thread t1 = new ItemsProducer(f2Queue);
Thread t2 = new F2ExecutorThread(f2Queue, f3Queue);
Thread t3 = new F3ExecutorThread(f3Queue);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
}
/**
* Thread producing 5 items at a time and feeding it to f1()
*/
class ItemsProducer extends Thread {
private BlockingQueue<Item> f2Queue;
private static final int F1_BATCH_SIZE = 5;
public ItemsProducer(BlockingQueue<Item> f2Queue) {
this.f2Queue = f2Queue;
}
public void run() {
Random random = new Random();
while (true) {
try {
List<Item> items = new ArrayList<>();
for (int i = 0; i < F1_BATCH_SIZE; i++) {
Item item = new Item(String.valueOf(random.nextInt(100)));
Thread.sleep(20);
items.add(item);
System.out.println("Item produced: " + item);
}
// Feed items to f1
f1(items);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void f1(List<Item> items) throws InterruptedException {
Random random = new Random();
for (Item item : items) {
Thread.sleep(100);
item.upc = String.valueOf(random.nextInt(100));
f2Queue.put(item);
}
}
}
/**
* Thread consuming items produced by f1(). It takes 20 items at a time, but if they are not
* available it waits and starts processesing as soon as one gets available
*/
class F2ExecutorThread extends Thread {
static final int F2_BATCH_SIZE = 20;
private BlockingQueue<Item> f2Queue;
private BlockingQueue<Item> f3Queue;
public F2ExecutorThread(BlockingQueue<Item> f2Queue, BlockingQueue<Item> f3Queue) {
this.f2Queue = f2Queue;
this.f3Queue = f3Queue;
}
public void run() {
try {
List<Item> items = new ArrayList<>();
while (true) {
items.clear();
if (f2Queue.drainTo(items, F2_BATCH_SIZE) == 0) {
items.add(f2Queue.take());
}
f2(items);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
void f2(List<Item> items) throws InterruptedException {
Random random = new Random();
for (Item item : items) {
Thread.sleep(100);
item.price = random.nextInt(100);
f3Queue.put(item);
}
}
}
/**
* Thread consuming items produced by f2(). It takes 20 items at a time, but if they are not
* available it waits and starts processesing as soon as one gets available.
*/
class F3ExecutorThread extends Thread {
static final int F3_BATCH_SIZE = 20;
private BlockingQueue<Item> f3Queue;
public F3ExecutorThread(BlockingQueue<Item> f3Queue) {
this.f3Queue = f3Queue;
}
public void run() {
try {
List<Item> items = new ArrayList<>();
while (true) {
items.clear();
if (f3Queue.drainTo(items, F3_BATCH_SIZE) == 0) {
items.add(f3Queue.take());
}
f3(items);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void f3(List<Item> items) throws InterruptedException {
Random random = new Random();
for (Item item : items) {
Thread.sleep(100);
item.competitorName = String.valueOf(random.nextInt(100));
System.out.println("Item done: " + item);
}
}
}
class Item {
String sku, upc, competitorName;
double price;
public Item(String sku) {
this.sku = sku;
}
public String toString() {
return "sku: " + sku + " upc: " + upc + " price: " + price + " compName: " + competitorName;
}
}
I guess you can follow the exact same approach in .Net as well. For better understanding I suggest you to go through basic architecture of http://storm.apache.org/releases/current/Tutorial.html
I tried to do same thing in .NET and i think it is working.
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace BlockingCollectionExample
{
class Program
{
static void Main(string[] args)
{
BlockingCollection<Listing> needUPCJobs = new BlockingCollection<Listing>();
BlockingCollection<Listing> needPricingJobs = new BlockingCollection<Listing>();
// This will have final output
List<Listing> output = new List<Listing>();
// start executor 1 which waits for data until available
var executor1 = Task.Factory.StartNew(() =>
{
int maxSimutenousLimit = 5;
int gg = 0;
while (true)
{
while (needUPCJobs.Count >= maxSimutenousLimit)
{
List<Listing> tempListings = new List<Listing>();
for (int i = 0; i < maxSimutenousLimit; i++)
{
Listing listing = new Listing();
if (needUPCJobs.TryTake(out listing))
tempListings.Add(listing);
}
// Simulating some delay for first executor
Thread.Sleep(1000);
foreach (var eachId in tempListings)
{
eachId.UPC = gg.ToString();
gg++;
needPricingJobs.Add(eachId);
}
}
if (needUPCJobs.IsAddingCompleted)
{
if (needUPCJobs.Count == 0)
break;
else
maxSimutenousLimit = needUPCJobs.Count;
}
}
needPricingJobs.CompleteAdding();
});
// start executor 2 which waits for data until available
var executor2 = Task.Factory.StartNew(() =>
{
int maxSimutenousLimit = 10;
int gg = 10;
while (true)
{
while (needPricingJobs.Count >= maxSimutenousLimit)
{
List<Listing> tempListings = new List<Listing>();
for (int i = 0; i < maxSimutenousLimit; i++)
{
Listing listing = new Listing();
if (needPricingJobs.TryTake(out listing))
tempListings.Add(listing);
}
// Simulating more delay for second executor
Thread.Sleep(10000);
foreach (var eachId in tempListings)
{
eachId.Price = gg;
gg++;
output.Add(eachId);
}
}
if (needPricingJobs.IsAddingCompleted)
{
if(needPricingJobs.Count==0)
break;
else
maxSimutenousLimit = needPricingJobs.Count;
}
}
});
// producer thread
var producer = Task.Factory.StartNew(() =>
{
for (int i = 0; i < 100; i++)
{
needUPCJobs.Add(new Listing() { ID = i });
}
needUPCJobs.CompleteAdding();
});
// wait for producer to finish producing
producer.Wait();
// wait for all executors to finish executing
Task.WaitAll(executor1, executor2);
Console.WriteLine();
Console.WriteLine();
}
}
public class Listing
{
public int ID;
public string UPC;
public double Price;
public Listing() { }
}
}

Unity pause text display in between stanzas wait for user input

I have a script that currently displays dialogue text letter by letter. Currently it rolls through each string of text in my _stanzas array without pausing. I would like to change this script so that it requires the user to press "Z" on their keyboard before the script begins to print the next block of text from _stanzas. I cant seem to figure it out...here is my code.
using UnityEngine;
using System.Collections;
public class Text : MonoBehaviour {
public float LetterPause = 0.1f;
public GameObject text;
public GameObject box;
public GameObject name;
private bool _textFinished;
private int _textIndex;
private string[] _stanzas;
int tracker;
public void Start()
{
if (Application.loadedLevel == 1) {
_stanzas = new [] {
" It’s Terrence’s hat... ",
"He always was one to lose track of the" + "\n" + "material objects in life," + "\n" + "but to hold onto the immaterial forever.",
"I’ll carry it for him" + "\n" + "until I find him. "
};
}
_textFinished = true;
_textIndex = -1;
tracker = _textIndex;
}
public void Update()
{
if (_textFinished)
{
if (_textIndex++ >= (_stanzas.Length - 1))
{
_textFinished = false;
text.SetActive(false);
box.SetActive(false);
name.SetActive(false);
}
if (_textFinished){
SetText(_stanzas[_textIndex]);}
}
}
private IEnumerator TypeText(float waitTime, string text)
{
_textFinished = false;
guiText.text = "";
foreach (var letter in text)
{
guiText.text += letter;
yield return new WaitForSeconds (waitTime);
}
_textFinished = true;
}
private void SetText(string text)
{
StartCoroutine(TypeText(LetterPause, text));
}
}
change
if (_textFinished)
to
if (_textFinished && (Input.GetKeyDown(KeyCode.Z) || _textIndex < 0))

Algorithm to fire sequential keystrokes

I want to write an algorithm to sequentially press keys F1-F3. My form has these controls:
lblF1
textboxF1
lblF2
textboxF2
lblF3
textboxF3
btnStart
In textboxF1-textboxF3 the time in seconds is entered. This when the program is to press the hotkey. It is important that the program can't press two keys at once, for example F1 and F2. It may not press more than one key in a second. When I click on btnStart it calls Run().
This is how I tried to resolve this:
static int counterF1 = 9999;
static int counterF2 = 9999;
static int counterF3 = 9999;
public void Run()
{
counterF1 = 9999;
counterF2 = 9999;
counterF3 = 9999;
while (true)
{
Loop();
}
}
public void Loop()
{
bool used = false;
if (counterF1 >= (int)textboxF1.text)
{
counterF1 = PressKey(VK_F1);
used = true;
}
if (counterF2 >= (int)textboxF2.text)
{
counterF2 = PressKey(VK_F2);
used = true;
}
if (counterF3 >= (int)textboxF3.text)
{
counterF3 = PressKey(VK_F3);
used = true;
}
if (used == false)
{
IncrementCounters();
Delay(1000);
}
}
public double PressKey(uint key)
{
myPostMessageA(hWindow, WM_KEYDOWN, (uint)key, (uint)key);
IncrementCounters();
return 1; //return 1 because one second
}
public void IncrementCounters()
{
counterF1++;
counterF2++;
counterF3++;
}
But often it doesn't press any key (it is possible it is too late, but can't be an omission). Can you explain how to make an algorithm for this?
We will use a class KeyStroke that stores the necessary data for a special key:
public class KeyStroke
{
public int period { get; set; } // Period in which to hit key
public int next { get; set; } // ticks to the next hit of this key
public int VK { get; set; } //KeyCode
}
public List<KeyStroke> keys = new List<KeyStroke>();
An Initialize() method is needed to read the data from the text boxes and to init the simulation. We utilize a timer with the interval of one second to run the simulation. In my example, I don't read from textboxes, but use constant values. Add the input and error handling. If you use WPF, you can bind the KeyStroke objects to the textboxes.
void Init()
{
//Initialize keys with according periods from input
keys.Clear();
keys.Add(new KeyStroke() { VK = VK_F1, period = 1, next = 1 });
keys.Add(new KeyStroke() { VK = VK_F2, period = 10, next = 10 });
keys.Add(new KeyStroke() { VK = VK_F3, period = 5, next = 5 });
//sort keys by period (descending), in order to handle long period keys, too
keys.Sort((first, second) => second.period.CompareTo(first.period));
//Start the program
var t = new DispatcherTimer();
t.Interval = TimeSpan.FromSeconds(1);
t.Tick += new EventHandler(t_Tick);
t.Start();
}
The tick event is similar to yours:
void t_Tick(object sender, EventArgs e)
{
bool used = false;
foreach (var key in keys)
{
if (key.next <= 0 && !used)
{
PressKey(key.VK);
key.next = key.period;
used = true;
}
key.next--;
}
}

adding Double click event in CellTable cell - GWT

I am unable to figure out how could I add a double click event to the cell of the CellTable.
Is it possible with GWT CellTable or not?
Is there any workaround
thank you..
al
BTW, i saw this post but there is no reply...
http://www.devcomments.com/Adding-DoubleClicks-and-OnContextMenu-to-CellTable-at1066168.htm
I crafted something different that just fit my needs:
cellTable.addCellPreviewHandler(new Handler<TitoloProxy>() {
long lastClick=-1000;
#Override
public void onCellPreview(CellPreviewEvent<TitoloProxy> event) {
long clictAt = System.currentTimeMillis();
GWT.log("clickAt: "+(clictAt));
GWT.log("lastClick: "+(lastClick));
if(event.getNativeEvent().getType().contains("click")){
GWT.log(""+(clictAt-lastClick));
if(clictAt-lastClick < 300) { // dblclick on 2 clicks detected within 300 ms
Window.alert("I am a double click crafted event!");
}
lastClick = System.currentTimeMillis();
}
}
});
cellTable.addDomHandler(new DoubleClickHandler() {
#Override
public void onDoubleClick(DoubleClickEvent event) {
Window.alert("That's it!");
}
}, DoubleClickEvent.getType());
Integer row=0;// to hold row index
Integer column=0;// to hold column index
_Grid.addCellPreviewHandler(new CellPreviewEvent.Handler<Model>() {
// this is to handle row id
#Override
public void onCellPreview(final CellPreviewEvent<Model> event) {
if (BrowserEvents.CLICK.equalsIgnoreCase(event.getNativeEvent().getType())) {
row = event.getIndex();
column=event.getColumn();
}
}
});
// because Doubleclick handler doesn't give row index or column index we will use addCellPreviewHandler to return row index or column index.
_Grid.addDomHandler(new DoubleClickHandler() {
#Override
public void onDoubleClick(final DoubleClickEvent event) {
System.out.println(" You clicked row = " + row);
System.out.println(" You clicked column = " + column);
}
}, DoubleClickEvent.getType());
For cell lists, this code works ok:
cellList.addDomHandler(new DoubleClickHandler() {
#Override
public void onDoubleClick(DoubleClickEvent event) {
// do the stuff
}
}, DoubleClickEvent.getType());
I'm not sure about table cells
Because the CellPreview interface does not natively capture double click events you will need add event logic into the Overriden onCellPreview method. First you would think the best way would be to check the click time differences. However it is much more efficient and elegant to use a state machine and count clicks. This is more robust and allows you to deal with multiple event cases - Such as mouse hover, single, and double clicks. The code is pretty straightforward. So enjoy!
public class CellHoverHandler implements Handler<T> {
Timer singleClickTimer;
int clickCount = 0;
int clickDelay = 300;
#Override
public void onCellPreview(final CellPreviewEvent<T> event) {
if (Event.getTypeInt(event.getNativeEvent().getType()) == Event.ONMOUSEOVER) {
handleOnMouseOver(event);
} else if (Event.getTypeInt(event.getNativeEvent().getType()) == Event.ONCLICK) {
clickCount++;
if (clickCount == 1) {
singleClickTimer = new Timer() {
#Override
public void run() {
clickCount = 0;
handleOnClick(event);
}
};
singleClickTimer.schedule(clickDelay);
} else if (clickCount == 2) {
singleClickTimer.cancel();
clickCount = 0;
handleOnDblClick(event);
}
}
}
private void handleOnMouseOver(CellPreviewEvent<T> event) {
Element cell = event.getNativeEvent().getEventTarget().cast();
GWT.log("mouse over event");
}
private void handleOnClick(CellPreviewEvent<T> event) {
Element cell = event.getNativeEvent().getEventTarget().cast();
GWT.log("click event");
}
private void handleOnDblClick(CellPreviewEvent<T> event) {
Element cell = event.getNativeEvent().getEventTarget().cast();
GWT.log("double click event");
}
OPTIMIZATION: feel free to stick the count, timer, and delay as static class members or global members to reuse. Also check to see if the timer is null before making a new instance. I had omitted this for simplicity. Unlike a lot of other techniques this way still provides you with easy and direct access to the cell event. The technique with overloading the AbstractCell works well too, however sometimes you really don't have custom cells or want to make a custom cell to just handle events on the cell.
Leaving this here for future reference
private Set<GenericEventHandler<T>> dblClickHandlers = new HashSet<>(4);
dblClickHandlers simply maps interface implementations of my choice
table.addCellPreviewHandler(event -> {
if (BrowserEvents.DBLCLICK.equalsIgnoreCase(event.getNativeEvent().getType())) {
LOGGER.info("dblclick (native) " + event.getIndex() + " " + event.getColumn() + "; " + event.getValue());
dblClickHandlers.forEach(handler -> {
handler.onEvent(event.getValue());
});
}
});
table.sinkBitlessEvent(BrowserEvents.DBLCLICK);
The trick is to sink the 'dblclick' event.
If you wanted a text cell that allows you to support your own chosen list of events, you can use this:
public class EventfulTextCell extends AbstractSafeHtmlCell`<String`> {
private static final String[] NO_CONSUMED_EVENTS = null;
public EventfulTextCell() {
this(NO_CONSUMED_EVENTS);
}
public EventfulTextCell(String... consumedEvents) {
super(SimpleSafeHtmlRenderer.getInstance(), consumedEvents);
}
#Override
public void render(Context context, SafeHtml value, SafeHtmlBuilder sb) {
if (value != null) {
sb.append(value);
}
}
}
Then you instantiate it:
new EventfulTextCell("click", "dblclick")
Then override the onBrowserEvent() method to process your events.

Add buttons to a ListField in BlackBerry

I am using a ListField in BlackBerry and want to include a button with two text fields in the row like:
Button
Text1
Text2
But I am not able to add the buttons. All the help I've found is about adding images.
Take a look at How to customize list field in blackberry and Blackberry - how to add fields to listfield
by default ... list field provides the focus on a single row as a whole....and not to the single field on a row(as u told that u want to add three fields....buttons, textfield, textfield).
so i want to know why do u want to add buttons and two separate text-fields in a single row... I think its not easy if u want to get focus only on button OR only on a text-field....in a single row of a list field.
by the way... here is the sample code........ how u create three fields in a single row of list field...
just call the constructor of this list-field class in ur main screen's class and add it like.....
DetailListField _listField = new DetailListField();
add(_listField);
DetailListField class -
class DetailListField extends ListField implements ListFieldCallback
{
private Vector rows;
private Font font;
public DetailListField()
{
this(0, ListField.USE_ALL_WIDTH | DrawStyle.LEFT);
}
public DetailListField(int numRows, long style)
{
super(0, style);
try
{
rows = new Vector();
font = Font.getDefault().derive(Font.PLAIN, 7, Ui.UNITS_pt);
setRowHeight(-2);
setCallback(this);
for (int x = 0 ; x < 5 ; x++)
{
TableRowManager row = new TableRowManager();
// button, textfield, textfield
ButtonField _btn = new ButtonField("Button", ButtonField.CONSUME_CLICK);
_btn.setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(new XYEdges(1,1,1,1),
new XYEdges(0x557788, 0xAA22BB, 0x557788, 0xAA22BB),
Border.STYLE_SOLID));
row.add(_btn);
BasicEditField _basicEdit1 = new BasicEditField(BasicEditField.EDITABLE | BasicEditField.FILTER_DEFAULT);
_basicEdit1.setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(new XYEdges(2,2,2,2),
new XYEdges(0x557788, 0xAA22BB, 0x557788, 0xAA22BB),
Border.STYLE_SOLID));
row.add(_basicEdit1);
BasicEditField _basicEdit2 = new BasicEditField(BasicEditField.EDITABLE | BasicEditField.FILTER_DEFAULT);
_basicEdit2.setBorder(VISUAL_STATE_NORMAL, BorderFactory.createSimpleBorder(new XYEdges(2,2,2,2),
new XYEdges(0x994422, 0xAA22BB, 0x994422, 0xAA22BB),
Border.STYLE_SOLID));
row.add(_basicEdit2);
// add id to the vector.
rows.addElement(row); // returnData[x][0]);
// call draw list row
// then call constructor of manager class
}
setSize(rows.size());
invalidate();
} catch(Exception e) {
}
}
public void drawListRow(ListField list, Graphics g, int index, int y, int width)
{
try
{
DetailListField dl = (DetailListField)list;
TableRowManager rowManager = (TableRowManager)dl.rows.elementAt(index);
rowManager.drawRow(g, 0, y, width, list.getRowHeight());
} catch(Exception e) {
}
}
protected boolean keyChar(char key, int status, int time)
{
if (key == Characters.ENTER)
{
return true;
// We've consumed the event.
}
else if(key == Characters.ESCAPE)
{
return true;
}
return super.keyChar(key, status, time);
}
protected boolean navigationClick(int status, int time)
{
try
{
// use below method if want to get label value from manager.
final int index = this.getSelectedIndex();
if(index >= 0) {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert("Selected index number : " + (index + 1));
}
});
}
} catch (final Exception e) {
}
return true;
}
public Object get(ListField listField, int index)
{
// TODO Auto-generated method stub
return rows.elementAt(index);
}
public int getPreferredWidth(ListField listField)
{
// TODO Auto-generated method stub
return 0;
}
public int indexOfList(ListField listField, String prefix, int start)
{
// TODO Auto-generated method stub
return rows.indexOf(prefix, start);
}
/**
* MANAGER CLASS
*/
private class TableRowManager extends Manager
{
int _height = 0, _width = 0;
int yPos = 0;
public TableRowManager()
{
super(0);
}
// Causes the fields within this row manager to be layed out then
// painted.
public void drawRow(Graphics g, int x, int y, int width, int height)
{
try
{
_height = height;
_width = getPreferredWidth();
yPos = y;
// Arrange the cell fields within this row manager.
// set the size and position of each field.
layout(_width, _height);
// Place this row manager within its enclosing list.
setPosition(x, y);
// Apply a translating/clipping transformation to the graphics
// context so that this row paints in the right area.
g.pushRegion(getExtent());
// Paint this manager's controlled fields.
subpaint(g);
g.setColor(0x00CACACA);
g.drawLine(0, 0, getPreferredWidth(), 0);
// Restore the graphics context.
g.popContext();
} catch(Exception e) {
System.out.println("Exeception : (DetailListField) 4 : " + e.toString());
}
}
// Arranges this manager's controlled fields from left to right within
// the enclosing table's columns.
protected void sublayout(int width, int height)
{
try
{
// set the bitmap field
Field _field0 = getField(0);
layoutChild(_field0, (_width/3) - 30 , _height - 20);
setPositionChild(_field0, 2, 5);
// set the name field
Field _field1 = getField(1);
_field1.setFont(font);
layoutChild(_field1, (_width/3) - 30, _field1.getPreferredHeight());
setPositionChild(_field1, (_width/3) - 30 + 10, 5);
Field _field2 = getField(2);
_field2.setFont(font);
layoutChild(_field2, (_width/3) - 30, _field2.getPreferredHeight());
setPositionChild(_field2, ((_width/3) - 30)*2 + 20, 5);
setExtent(_width, _height);
} catch(Exception e) {
System.out.println("Exeception : (DetailListField) 5 : " + e.toString());
}
}
// The preferred width of a row is defined by the list renderer.
public int getPreferredWidth()
{
return (Display.getWidth());
}
// The preferred height of a row is the "row height" as defined in the
// enclosing list.
public int getPreferredHeight()
{
return _height;
}
}
}
bt still i dont know how to get focus on single field of a single row...
usage:
ListCallBack _callBack = new ListCallBack();
_countries.setCallback(_callBack);
code:
private class ListCallBack implements ListFieldCallback{
public void drawListRow(ListField listField, Graphics graphics,
int index, int y, int width) {
for(int i = 0; i <= 23; i++) {
graphics.drawBitmap(0, y, 48, 48, (Bitmap) MyApp._flagVector.elementAt(index), 0, 0);
}
String text = (String)MyApp._countryVector.elementAt(index);
graphics.drawText(text, 65, y, 0, width);
}
public Object get(ListField listField, int index) {
return MyApp._countryVector.elementAt(index);
}
public int getPreferredWidth(ListField listField) {
return Display.getWidth();
}
public int indexOfList(ListField listField, String prefix, int start) {
return MyApp._countryVector.indexOf(prefix, start);
}
}

Resources