views:

130

answers:

6

I have a static method which sets a variable:

static String[] playersNames;
public static void setParameters(String[] players) {
playersNames = players;
}

Then I have a static block:

static {
    JRadioButton option;
    ButtonGroup group = new ButtonGroup();
    // Wright a short explanation of what the user should do.
    partnerSelectionPanel.add(new JLabel("Pleas select a partner:"));
    // Generate radio-buttons corresponding to the options available to the player.
            // Bellow is the problematic line causing the null pointer exception:
    for (String playerName: playersNames) {         
        final String pn = playerName;
        option = new JRadioButton(playerName, false);
        option.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent evt) {
                partner = pn;
            }
        });
        partnerSelectionPanel.add(option);
        group.add(option);
    }
    partnerSelectionPanel.add(label);
    // Add the "Submit" button to the end of the "form".
    JButton submitButton = new JButton("Submit");
    submitButton.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent evt) {
            partnerSelected();
        }
    });
    partnerSelectionPanel.add(submitButton);
}

Compiler does not complain about anything but when I try to execute the code I get problems. In this place SelectPartnerGUI.setParameters(players); I have:

Exception in thread "main" java.lang.ExceptionInitializerError.

and it is cause by java.lang.NullpointerException at this place for (String playerName: playersNames).

Does my program do not see the palyersNames?


The first time I refer to the class in this way: SelectPartnerGUI.setParameters(players);. And in my class I have the setParameters method before the problematic static block. So, why this static block is called before the setParameters method is called?

A: 

I can't the the part where you initialize your static variable playersNames.

It is null, when you reach your loop. You have to set a value for the variable first (e.g. by calling the setter).

lajuette
+2  A: 

This is logical, because the variable is not initialized

And the static block is executed whenever the class is accessed for the first time.

Therefore, at that point, the static variable is still null.

To solve this problem - either set an initial value of the variable, or (perhaps better regarding the usecase) - change the static initialization block to a static method and call it only after you have called the setter.

Bozho
I ask my class for the first time by `SelectPartnerGUI.setParameters(players);`. So I thought that the `setParameters` method will be called first and then the static block will be executed (which is placed after the `setParameters` method).
Roman
no - it will be executed before the setter.
Bozho
As I answered in my post, static blocks are run even before the constructor
Shervin
+8  A: 

Any static initializer blocks get executed as soon as the class get loaded. You can impossibly call a method on a class before the static initializer runs. You'll need to set the playersNames in the static initializer block itself. Keep in mind that they're executed in the order as they appear in the code. A better approach IMO is to rewrite the whole thing and make use of a constructor to construct a class.

Update: as per your edit:

The first time I refer to the class in this way: SelectPartnerGUI.setParameters(players);. And in my class I have the setParameters method before the problematic static block. So, why this static block is called before the setParameters method is called?

The static block is called as soon as the class get loaded. This already happens when the JVM encounters SelectPartnerGUI for the first time. You cannot call any (static) methods on a class before it's loaded by JVM. It's like that you cannot drive the car before you turn on the engine .

BalusC
I wanted to construct my class as a set of static method. The reason for that is that I would have only one instance of the class. So, I thought it is a bed idea to use constructors and instantiate the class. But then I have realized that I have problems with the static fields of the class. I do not know how to set the values of these field from "outside".
Roman
@Roman if you really need only a single instance you should use the singleton pattern. In this case however an application-modal dialog might be what you actually want.
extraneon
Then *just* construct only one instance of it. That you think that there's ever only one instance of it does not necessarily mean that you need to make everything static. Some people have only one car, that still doesn't mean that you should make the car static. By the way: the singleton pattern is likely not applicable here. You have full control over the code. As said, just create only one instance of it and reuse it forever. That's all.
BalusC
+2  A: 

Remember that in java, if you have a static block, this will run before the constructor. Thus your playersName is initialized after your static block has run. You should not run these type of code in static blocks.

Shervin
A: 

your static initialization block will run the first time you access the class, before the invocation of setParameters()

hatchetman82
A: 

As all the others said, static blocks are executed on class load, far before you do anything with the class.

Apart from that, the design seems a bit dubious to me. You don't really see software developed as a sequence of static blocks all that much :)

I would definitely recommend the swing tutorial for you.

Further, rename setParameters to setPlayers to better reflect what you're doing, and trigger a a possible update to the partnerSelectionPanel when setPlayers is called. You probably want to refresh that panel every time it is shown, unless players is unchanged.

extraneon