Page 1 of 1

Why does this code not work?

Posted: Sat Feb 19, 2022 8:43 am
by UrbanCyborg
What I'm trying to do is parameterize accessing numbers of labels, knobs, etc. by creating arrays of references to them, then accessing those arrays using for loops (I did use ranged for loops, or whatever they're called in Java, but I need the index for other purposes, so I changed them back). One example of code that's not working is:

Code: Select all

    private VoltageLabel[] fieldLabel   = { field1Label, field2Label, field3Label, field4Label,
                                            field5Label, field6Label, field7Label, field8Label };

    for(int iDex = 0; iDex < fieldLabel.length; ++iDex) {
        fieldLabel[iDex].SetText(String.valueOf(iDex + 1));
    }
where field1Label et al. are defined in the interface (i.e., Design Editor). Unfortunately, this doesn't work, nor does code that tries to compare against the array object references. My expertise is in C++, and I've basically been learning Java from the v 17 Language Spec (not the best way to do it, I know, but guaranteed to be "right"). Either there's something fundamental I don't understand about Java, or VM doesn't support this kind of usage. Maybe both. :? I hope code like this can work, because I'm tired of typing in hordes of individual cases.

Re: Why does this code not work?

Posted: Sat Feb 19, 2022 11:31 am
by honki-bobo
I think this is an execution order problem.

GUI elements are initialized in the InitializeControls() method. If you have declared and initialized the fieldLabel array at the bottom of the Java file in the designer (where it says "Add your own variables and functions here"), then the text labels you're adding to the array are not yet initialized, thus there is no pointer to the label and the content of your array is a bunch of nulls. If you run your code in the debugging mode you should also see a NullpointerException.

The solution is to declare your array at the bottom of the file

Code: Select all

private VoltageLabel[] fieldLabel;
and then initialize it in the Initialize() method

Code: Select all

    fieldLabel   = { field1Label, field2Label, field3Label, field4Label,
                                            field5Label, field6Label, field7Label, field8Label };

    for(int iDex = 0; iDex < fieldLabel.length; ++iDex) {
        fieldLabel[iDex].SetText(String.valueOf(iDex + 1));
    }
That should do it.

Re: Why does this code not work?

Posted: Sat Feb 19, 2022 12:52 pm
by UrbanCyborg
I think you're right. It probably wouldn't have occurred to me anytime soon, although in C++, precisely when anything at global scope gets initialized is anyone's guess. I suppose I just figured that would be one of the things simplified out in Java. Silly me.

The problem is, doing it the way you suggest also doesn't work, and apparently for the same reason. Attempting to compile your version just gives me a long string of statements to the effect that { is an illegal start of expression, that my field names are not statements, and that commas should be replaced with semicolons. Pretty much the same messages I got before, in fact. Is Initialize() guaranteed to be called after InitializeControls()? Or could the compile be failing because the declaration of the arrays is at global scope, and thus, might run after the initialization code?

Re: Why does this code not work?

Posted: Sat Feb 19, 2022 1:03 pm
by honki-bobo
Sorry, I copy-pasted your example code instead of my test code :roll:

Try

Code: Select all

fieldLabel  = new VoltageLabel[] { field1Label, field2Label, field3Label, field4Label,
                                            field5Label, field6Label, field7Label, field8Label };

Re: Why does this code not work?

Posted: Sat Feb 19, 2022 3:18 pm
by UrbanCyborg
Roger that. Makes more sense now. :D

Re: Why does this code not work?

Posted: Sun Feb 20, 2022 11:51 am
by UrbanCyborg
Works gangbusters now. Thanks much, honki-bobo-san! One thing I'd forgotten about is that in Java, unlike C++, declaring an array doesn't actually allocate anything; you still have to use new to allocate and initialize an instance. That takes some getting used to.

Re: Why does this code not work?

Posted: Sun Feb 20, 2022 12:42 pm
by honki-bobo
That's great news. Glad we could sort this out.