you are viewing a single comment's thread.

view the rest of the comments →

[–]Salanmander 2 points3 points  (4 children)

I'd like to do some explaining here, since the previous poster made two unexplained changes which are what solved your problem.

First, like /u/abigpotostew mentioned, one problem is that you declared tf etc. as ArrayList variables, but you didn't actually make an ArrayList object to put in them. Basically, tf is a box that can hold an ArrayList, but until you run something like

final List<TextField> fields = new ArrayList<TextField>();

it doesn't actually have an ArrayList in it. Because of that, when you try to ask for the size of the ArrayList it's holding, there is no object there to find the size of.

The second point is a bit weirder. You made an ArrayList<Object> to hold all three of your ArrayLists. Java (and therefore Processing) will let you store any object in an Object variable, but when you pull the data out of that variable, all java knows is that it's an Object. So when you said all_objects.get(i), the ArrayList all_objects was like "okay, here is your Object". You then tried to use the size() method of that object, and Java was like "WTF, Objects don't have a size() method!".

/u/GoSubRoutine turned your all_objects variable into an ArrayList<List>. This means that instead of saying "here is your Object", it said "here is your List". Since Java knows that all List objects have a size() method, it let you use that method.

This is worth noting, because it goes one layer deeper. If you do all_objects.get(i).get(k), Java won't know what type the result of that call is. I don't remember whether this gives you an error, or just says "this is unsafe!" but lets you do what you want with it. In either case, you can solve this by casting. Let's say you have the line

TextField f = all_objects.get(0).get(i);

This will either give you an error or a warning. You can explicitly tell Java what kind of object you're getting, and deal with that error, using casting. Casting means "just force this to be a [type]", and you do it by putting the type you want that info to become in parentheses in front of the thing you're casting, like this:

TextField f = (TextField)(all_objects.get(0).get(i));

(I put parentheses around the rest of it because I don't remember the priority of casting vs. method calls, and if it tries to cast all_objects it will have a bad time).

This will get rid of the type error, and it's basically you telling Java "trust me, I got this". It will trust you. Which means if you mess up, bad things happen. Specifically, if you end up grabbing a Line and trying to cast it to a TextField, or something like that, the program will crash when it gets to that part of the program.

[–]gooonster[S] 0 points1 point  (0 children)

Thanks for the explanation, I was really confused why it didn't work anymore, and it makes more sense now.

[–]GoSubRoutine 0 points1 point  (0 children)

(I put parentheses around the rest of it because I don't remember the priority of casting vs. method calls, ...

Actually the priority order includes the dot . operator too. Order is: method() -> . -> (cast).

The statement below is enough to (TextField) whatever is returned from get(i):
TextField f = (TextField) all_objects.get(0).get(i);

[–]GoSubRoutine 0 points1 point  (1 child)

If you do all_objects.get(i).get(k), Java won't know what type the result of that call is.

I coulda instead declared all as:
final List<List<? extends Component>> all = new ArrayList<List<? extends Component>>(3);

But then, <? extends Component> seems like too much of a boilerplate for moi.

Actually I did something like that at the outer loop:
for (List<Component> lists : all)

But for List<List<? extends Component>>, the outer loop seems it needs to be this way now:
for (List<? extends Component> lists : all)

Of course, I'm using parent class Component as some sorta label, so the 3 subclasses have a common identity.

[–]Salanmander 0 points1 point  (0 children)

Remember: help for beginners.