how to add imageviews to gridpane using a forloop - loops

here's my code.this prompts a exception saying "IllegalArgumentException: Children: duplicate children added: parent = Grid hgap=5.0, vgap=5.0, alignment=TOP_LEFT"
File file = new File("D:\SERVER\Server Content\Apps\icons");
File[] filelist1 = file.listFiles();
ArrayList<File> filelist2 = new ArrayList<>();
hb = new HBox();
for (File file1 : filelist1) {
filelist2.add(file1);
}
System.out.println(filelist2.size());
for (int i = 0; i < filelist2.size(); i++) {
System.out.println(filelist2.get(i).getName());
image = new Image(filelist2.get(i).toURI().toString());
pic = new ImageView();
pic.setFitWidth(130);
pic.setFitHeight(130);
gridpane.setPadding(new Insets(5));
gridpane.setHgap(5);
gridpane.setVgap(5);
pic.setImage(image);
hb.getChildren().add(pic);
}

Adding Items to a GridPane is a little different.
From the Docs
To use the GridPane, an application needs to set the layout
constraints on the children and add those children to the gridpane
instance. Constraints are set on the children using static setter
methods on the GridPane class
Applications may also use convenience methods which combine the steps
of setting the constraints and adding the children
So in your example, you first need to decide : How many images do I need in one row ?
Lets say your answer is 4, then your code becomes : (There are diff approaches to it, I am writing down the simplest one. You can use anything, loops for rows and colums being a good alternative ;)
)
//Can be set once, no need to keep them inside loop
gridpane.setPadding(new Insets(5));
gridpane.setHgap(5);
gridpane.setVgap(5);
//Declaring variables for Row Count and Column Count
int imageCol = 0;
int imageRow = 0;
for (int i = 0; i < filelist2.size(); i++) {
System.out.println(filelist2.get(i).getName());
image = new Image(filelist2.get(i).toURI().toString());
pic = new ImageView();
pic.setFitWidth(130);
pic.setFitHeight(130);
pic.setImage(image);
hb.add(pic, imageCol, imageRow );
imageCol++;
// To check if all the 4 images of a row are completed
if(imageCol > 3){
// Reset Column
imageCol=0;
// Next Row
imageRow++;
}
}

Related

Remove child on all array movieclips

I was looking for a solution to removing lists of movieclips from the stage in as3. I had a go at adding the movieclips to an array and making a loop that removes each of them if they are present. I had to include the if contains because it was sending me back this without it: "Error #2025: The supplied DisplayObject must be a child of the caller."
var array: Array = new Array;
var symbol1: MovieClip = new Symbol1;
var symbol2: MovieClip = new Symbol1;
array.push(symbol1);
array.push(symbol2);
stage.addChild(array[1]);
for (var i = 0; i < array.length; i++) {
if (contains(array[i])) {
stage.removeChild(array[i]);
trace("removed symbol[i]");
}
}
Am I using arrays wrong?
Try with stage.contains(array[i])
For more modular code (you can reuse no matter the parent), try doing it this way:
for (var i = 0; i < array.length; i++) {
if (array[i].parent) { //check to see if this item has a parent
array[i].parent.removeChild(array[i]); //tell the parent to remove this child
trace("removed symbol [i]");
}
}
This way, if you decide later that you'd like to have all your items in a container instead of stage, you don't have to change the code.

Actionscript 3.0 Get all instances of a class?

I got a ton of movieclips in a class. Is there a more efficient way to apply a function to every instance in the class other than this?
var textArray:Array = [
interludes.interludeIntro.interludeBegin1,
interludes.interludeIntro.interludeBegin2,
interludes.interludeIntro.interludeBegin3,
interludes.interludeIntro.interludeBegin4,
interludes.interludeIntro.interludeBegin5,
interludes.interludeIntro.interludeBegin6,
interludes.interludeIntro.interludeBegin7,
//... ... ...
interludes.interludeIntro.interludeBegin15
];
for each (var interludeText:MovieClip in interludeBeginText)
{
interludeText.alpha = 0 //clear all text first
}
Also for some reason this doesn't work:
interludes.interludeIntro.alpha = 0;
It permanently turns that class invisible, even if I try to make specific instances visible later with:
interludes.interludeIntro.interludeBegin1.alpha = 1;
I have NO idea why the above doesn't work. I want to turn every single instance in the class interludeIntro invisible, but I want to turn specific instances visible later.
(btw I have no idea how to insert code on this website, pressing "code" doesn't do anything, so pardon the bad formatting)
I'm not really sure what you're asking, but what may be useful is that, in ActionScript you can refer to properties by name, like myObject["someProperty"].
Using that, you can iterate over properties if they follow some naming scheme, so for example:
for (var i:int = 1; i <= 15; i ++)
interludes.interludeIntro["interludeBegin" + i].alpha = 0;
That iterates over interludes.interludeIntro.interludeBegin1 through ...15 and sets their alpha properties to 0.
When you do that:
interludes.interludeIntro.alpha = 0;
you turn the movie clip and all its children invisible.
So later when you do that:
interludes.interludeIntro.interludeBegin1.alpha = 1;
You make the movie clip visible, but since its parent is still invisible, you don't see anything. The solution is to loop through the movie clips and make each of them invisible/visible.
// Keep the parent visible at all time
interludes.interludeIntro.alpha = 1;
for (var i:int = 0; i < textArray.length; i++) {
textArray[i].alpha = 0;
}
// Now this will work:
interludes.interludeIntro.interludeBegin1.alpha = 1;

BCB6: How to put elements of a form in an array?

I'm building a simple game in C++Builder6 and I have 42 Image objects on a Form... At start-up I want all Image objects to be disabled, so I wonder can I put all of them in an array and simply loop thorough the entire array and make them Disabled? I know there must be a way, but I'm just new to programming :)
You have several options.
First: You can declare
Image* array[40];
And dynamically construct the image.
for ( int i = 0 ; i < 40; ++i ) {
image[i] = new Image(this); // where "this" is pointer to your form
image[i]->Parent = this;
// option below are optional
image[i]->Height = 50;
image[i]->Width = 50;
image[i]->Left = 40;
image[i]->Top = 100;
image[i]->Tag = i;
image[i]->OnClick = ButtonClick; // connect with method
}
Second option is declare
Image* array[40];
and manually set all values;
array[0] = Image1;
...
array[39] = Image40;
Then you will have all image in array and you can use loop for doing something on all Image

Reordering an array in flash as3

I have an array of objects, each of which is assigned an ID when it is first created. I give the user the ability to visually reorder the objects, which changes their position in the array. They then have the option to save that order using a flash sharedObject or "cookie" and then later, if they reopen the flash file, I want them to be able to hit a button to restore that order. I'm just not sure what the syntax would be to set the object's index within the array. Here's my code:
VARIABLES:
var project_settings = SharedObject.getLocal("settings"); //saves all project settings for the next time the file is opened
var project_order:Array = []; //saves project order for the next time the file is opened
var project_display:Array = []; //saves whether each project should be displayed or hidden for the next time the file is opened
SAVE CODE:
function saveOrder(){
for (var i=0;i<project_array.length;i++){
project_order[i] = project_array[i].id;
project_display[i] = project_array[i].projectThumb.thumbActive;
}
project_settings.data.order = project_order;
project_settings.data.active = project_display;
//trace (project_settings.data.active[1]);
project_settings.flush(); //saves most recent "cookie"
}
RESTORE CODE:
function loadOrder(){
for (var i=0;i<project_array.length;i++){
/* NEED THE CODE THAT GOES HERE. BASICALLY, PROJECT_ARRAY[i] SHOULD BE THE ITEM WITH AN ID EQUAL TO PROJECT_SETTINGS.DATA.ORDER[i] */
}
}
Something like this should work:
function loadOrder()
{
var dict = new Dictionary();
for (var i = 0; i < project_array.length; i++)
dict[project_array[i].id] = project_array[i];
project_array = [];
for (var i = 0; i < project_settings.data.order.length; i++)
project_array[i] = dict[project_settings.data.order[i]];
}
Just load in your array and sort on the ID. Something like this should work:
private function _loadArray():void
{
// fill in your array
project_array.sort( this._sortFunc );
}
// replace the * by whatever your object type is
private function _sortFunc( a:*, b:* ):int
{
return a.id - b.id;
}
More info: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sort()
Or even the sortOn() function (which might be easier) should work:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Array.html#sortOn()

Flash AS 3 Loader OnComplete Inside a Loop

As a followup to the question, How to get associated URLRequest from Event.COMPLETE fired by URLLoader, how can I make the function work for loader object in a loop?
Here is my existing (rough) code; I always get the mylabel from the last element of the array.
var _loader = new Loader();
for (j = 0; j < 5; j++) {
//mylabel variable is correct setup in the loop
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void {
doneLoad(e, mylabel);
});
_loader.load(new URLRequest(encodeURI(recAC[j].url)));
}//for loop
As per the comments above, this won't work because:
1) You're just adding the same event listener 5 times to the loader.
2) You're just reseting your same loader object 5 times.
The final output will just be as though you only called it the last time.
There are a variety of ways to address this - loading stuff asynchronously is one of the great mindfucks of learning to code - but the simplest way is probably just to create five separate loaders.
I'd do something like this:
var loaders:Array = [];
var labels:Array = ["label1", "label2", "label3", "label4", "label5"];
for (var j:int = 0; j < 5; j++) {
loaders[j] = new Loader();
loaders[j].contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
loaders[j].load(new URLRequest(encodeURI(recAC[j].url)));
}
function completeHandler(e:Event):void {
doneLoad(e.currentTarget, labels[loaders.indexOf(e.currentTarget)]);
}
The confusing part is finding a good way to keep track of which load is associated with which label etc, since in theory your loads can finish in any order. That's why I've got a separate label array there, and then you just match up the desired label with the loader that just finished loading.
I hope that helps!
the line belove should work but it returns -1, always.
loaders.indexOf(e.currentTarget);
Here my code
for(i; i < total; i++){
imgLoaderArray[i] = new Loader();
imgLoaderArray[i].contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, urlError);
imgLoaderArray[i].contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);
imgLoaderArray[i].load(new URLRequest(xmlList[i].image));
}
function loaded(e:Event):void{
trace("index: "+imgLoaderArray.indexOf(e.currentTarget)); // return -1 every time
}

Resources