updating Label text within a Table through actors/cells within a GestureListener - libgdx

Perhaps I'm simply going about this the wrong way ...
However, I'd simply like to change the text within a specific Label based on the direction of a GestureListener.fling(). I've kept both the Screen and GestureListener implementations within the same class in order to reduce possible trivial nonsense for this question:
public class TestScreen implements Screen, InputProcessor, GestureDetector.GestureListener {
In the show() method, I have the following:
Label heading = new Label("1ST", skin);
heading.setName("heading");
table.addActor(heading);
In the fling() method, I have the following:
Label l = table.findActor("heading");
l.setText("2ND");
However, the text within that label does not change. I've attempted to add the following line to the fling() method and it returns successful, but the text still does not update.
table.swapActors(table.getActor("heading"), l);
In an effort to be thorough, I've attempted the following to no avail:
SnapshotArray<Actor> children = table.getChildren();
int i = children.indexOf(l, false);
children.set(i, l);
and this ...
((Label)children.get(i)).setText(l.getText());
I even went as far as changing the initial .addActor() to just .add() in order for the table's cells to get created/populated - then attempted to modify the values of the table cells within the fling() method ...
Cell c = table.getCell(l);
c.setActor(l);
and this too ...
Array<Cell> cells = table.getCells();
int i = cells.indexOf(c, true);
cells.get(i).setActor(l);
Nothing appears to update the text visually on the screen - however, if I step through the debugger, then the table's actor/cell text appears to be updated ... but the text shown on the screen is always unchanged ... there is bound to be something that I'm missing here ...

Try to call .invalidate() on the label - that should force it to update to the changed text.
The invalidate method invalidates this actor's layout, causing layout() to happen the next time validate() is called. This method should be called when state changes in the actor that requires a layout but does not change the minimum, preferred, maximum, or actual size of the actor (meaning it does not affect the parent actor's layout).

Related

How to Find Exact match of an Image in Sikuli with Java

Am new to Sikuli and trying to Automate Citirx Application. Need Help
Am trying to select a user role in a screen, The screen has multiple roles and hence i need to scroll down the screen and search for a particular Role and click the Role.
I have Captured image of a Particular Role that i need to select and used below Code. In the second Image i have highlighted the Role i need to select in Red
Below is the Code an Trying:
Creating a Method:
public static boolean clipExist(Screen screen, String clip )
{
Match m = screen.exists(clip);
if(m != null)
{
return true;
}
else
{
return false;
}
}
Using the Method:
while(! clipExist(screen, "C:\\Users\\Satish_D1\\workspace\\Sikuli Demo\\Images\\DownArrow.PNG"))
{
screen.wheel(1 , 3);
if(clipExist(screen, "C:\\Users\\Satish_D1\\workspace\\Sikuli Demo\\Images\\Roles\\UK\\ENTP\\GEDIS_SALES_SUPPORT_ORL_CPF2.0_UK_ENTP.PNG"))
{
screen.doubleClick("C:\\Users\\Satish_D1\\workspace\\Sikuli Demo\\Images\\Roles\\UK\\ENTP\\GEDIS_SALES_SUPPORT_ORL_CPF2.0_UK_ENTP.PNG",0);
break;
}
}
The image recognision uses per default a similarity of 0.7 (see description of Patterns in SikuliX Documentation). That means SikuliX looks for 'pretty similar' images. You can specify the similarity for the pattern recognision thanks to the method similar, or in your case use the method exact.
In your method clipExist, you should replace the name of the image:
Match m = screen.exists(clip);
by:
Match m = screen.exists(Pattern(clip).exact())
It seems SikuliX 1.1 experience some problem with finding the text on a screen, but recognition works. You might want to scan the entire text screen by screen and split the lines. Next compare each line with the required role and save the degree of similarity. Select the line with the biggest similarity. In Python/Jython exists a special function for that in difflib module.
similarity = difflib.SequenceMatcher(None, string_a, string_b)
Here are the alternatives that you can do.
First alternative: capture scrollbar
Capture the down arrow in the scrollbar
Capture the image when you reach the end of scrollbar. The image contains the scroll progress and the down arrow of the scrollbar
Click down arrow until you find image of (2)
This method have drawback i.e. when the number of items are dynamic, the visual appearance of (2) will be different especially the scroll progress. However, this can be tricked by capturing only the lower part of scroll progress and the arrow. Please note that your mouse may make difficulty in (3) because you may not find (2) when it is covered by mouse. To handle this, every time you click down arrow, you may hover your mouse a bit before checking for (2). This is the complete script:
down_arrow = "downarrow.png"
complete_scroll = "completescroll.png"
while not exists(complete_scroll):
click(down_arrow)
hover(Location(300, 200))
Second alternative, use keyboard (down key)
Click anywhere in the items to be scrolled and do some type(Key.DOWN) for the number of item you have. In case you have dynamic number of item, you may do type(Key.DOWN) for any number that always bigger than your number of items. Here is the script to do
inside_item = "inside.png"
for n in range(10000):
type(Key.DOWN)
Hope it helps
I used 's' as a screen class reference. Hence, once we get an image then we will set the region for the same followed by the required image where you want to click
public static void main(String args[])
{
Match m = s.find("IMAGE");
Region r = new Region(m.x+11, m.y+22,12,12);
r.click();
s.find("ENTPIMAGE.PNG");
r.click("ENTPIMAGE.PNG");
}

AS3: Boolean variables changing by themselves?

Yes, you've read the title correctly. It appears that somehow Boolean variables switch to true by themselves. This is the only way I can explain this. Is this somehow possible? I have a Boolean that is set to false and can only be changed under strict conditions, but somehow it gets changed anyway, along with all the other Boolean variables. Any logical explanation for this?
Since you provide no code, I'll answer giving you ability to find out what is changing your variable.
Since you mention you are using FlashDevelop, I'll give you a FlashDevelop specific answer.
As noted by comments, using a getter/setter method will allow you to put a break point in your code. So instead of something like private var myBool:Boolean; do this:
private var myBool_:Boolean = false; //the actual var
public function get myBool():Boolean { return myBool; }
public function set myBool(val:Boolean):void {
myBool_ = val;
}
Now in flash develop, set a break point on this line: myBool_ = val;. To set a break point, click just to the left of the line in the gutter (see where the red dot is in the screenshot)
Run your code, look over to the Stack panel, and double click the the second line. That will show you what is setting your variable.
Larger Image

AS3/Air/Starling mobile app textinput class and how to get text value when in a class

I have a mobile app built in as3/air for mobile devices and I am wondering what the best approach to handle textinput fields are.
What I mean is I have multiple input fields on multiple screens. The inputs have a label (textfield), background color under the label (quad) and an input (textinput). Some are password, some are not. Some are different width/heights, multi-line/single line etc. All however use embedded fonts, have a name and ID assigned etc.
I have created a class file that extends Sprite and built all the components of the textinput (textfield, quad, textinput) so my other classes/screens can just create a new instance of this class passing custom values.
var textField:TextFieldClass = new TextFieldClass();
textField.DrawTextField(name, ID, width, height, isPassword, hasLabel, labelPosition etc);
The above works great. I can reuse the class to draw multiple textinput on screen with minimal code however I am having trouble getting the text value/ID/name when there are multiple instances.
I have tried adding each textField instance into an array and iterating through but that gets x number of the last textField instance e.g. if first instance is named txtEmail and the second is txtPassword, I get 2 txtPasswords.
I have also tried getChildByName and specifying the name of the textinput but when I use txtEmail I get a cannot access null value but txtPassword works.
Maybe I am going about this wrong so happy to use a better approach if one exists (which I am sure there is). Basically I would like to have a reusable textinput class that allows custom design (quads, fonts etc) without having to copy paste the entire textinput code for each new input field.
Thanks

Making HTML elements access a dynamically generated value

So I am making a data entry program where the user presses buttons to generate new inputs (numbers text etc.) and when finished the lists are generally between 100-10000 items.
The program has been coming along well, but now I am at a point where one set of data entered must generate the coices for an array [1,2, . . .] which is part of a later set of data.
So what I have done is setup buttons with the ID based on the earlier inputs. (The whole data set is saved as a JSON)
And what I want to do is when the button is pressed it looks pressed and writes to an HTML element the ID of the button which will later be read and saved to JSON.
My problem is centered on getting the correct information back to the user.
function doStuff(container){
for (var u = 0, c = someJSON.length; u < c; u++){
var someButton = document.createElement('button');
someButton.id = someJSON.id;
someButton.className = 'someButton';
someButton.onclick = function() {
writeIDToHTML(container,someButton,someButton.id);
}
container.appendChild(someButton);
}
}
function writeIDToHTML(container,theButton,theID){
console.log("theID")
console.dir(theID)
}
This prints only the last ID in the loop. How do I get each ID to each button?
The other thing to do is to give the button a pressed look.
Bonus points if it is reversable.
You should not add a listener on each element. The way to do it is adding a listener on the container and get the id of the clicked event (via event.target). This is called event delegation.
I could explain it, but this guys made a perfect answer to your question : http://davidwalsh.name/event-delegate
Btw, you should consider using a library like jquery to manipulate your DOM. It implements event delegation and advanced cross browser DOM manipulation utilities. For instance, you would not need to add a 'container' property since you can access it by the parent() method.

How to copy Input Text Value into Dynamic Text that is in a MovieClip1 Inside a MovieClip2

Current my code is as such
setcustomlocation.addEventListener(MouseEvent.CLICK,customlocation2);
function customlocation2(e:MouseEvent):void
{
locationinput.text = FlashingWon.Won1.name.text;
}
I'm trying to make it such that it would copy the input text field values into a dynamic text. However, it throws up the error that
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at main/customlocation2()[main::frame1:9]
Which can I only assume that it is not able to communicate with the dynamic text field in the movieclip within another movieclip.
First, you can be 100% sure that it CAN communicate with the dynamic TextField in the MovieClip.
From you description I understand that you wish to copy from input into dynamic. But from your code I see that you take from the dynamic into the input, please check that out:
// This will copy in such a way: input <= wonText
locationinput.text = FlashingWon.Won1.name.text;
// This will copy from input
FlashingWon.Won1.name.text = locationinput.text;
Anyhow, the error that you get has nothing to do with this, it's rather like you already noticed, that one of your TextField is not 'found'. For this I recommend you a best practice: To create instances of the objects you want to use and populate them from the stage through the getChildByName method. This way you will promptly now (specially if you do this on construction or init) if you had any misspelling or miss structure on the childs you want to get.
like so:
var inputText: TextField;
var dynoText: TextField;
In your Constructor or else where at a soon level, give to your vars the proper value:
inputText = getChildByName('locationinput') as TextField;
dynoText = FlashingWon.Won1.getChildByName('name') as TextField;
This way you will soon enough know if one of this 2 textFields were not found under the object you give, and you have only one place to miss spell it. Also you will get code completion on your TextFields.
Finally the copy text part:
dynoText.text = inputText.text;
Hope it helps.
Alright, sorry for the delay, I was out on holidays.
I have opened your example and can see where the problems are:
1) You are trying to reach the FlashingWon when initiating the dynoText on the FIRST frame like so var dynoText = FlashingWon.Won1.getChildByName('name_txt'); BUT the FlashingWon element is ONLY available on the FIFTH frame. Meaning that you cannot refer to it quite yet, unless you add it on the first frame and make in invisible till the fifth frame. (You can make it visible in the goto1 function if you wish after the goToAndStop(5) line)
2) You called the TextField on the Won1 element 'name' which is a restricted sting in AS3, so change it to name_txt or label if you wish and it will work.
Let me know how it worked.