Alexandre van Wesel Alexandre van Wesel - 6 months ago 18
Java Question

Java programming : setActionCommand() error

I am developping a multiplayer Tetris-like game, with an RMI included. I have an interface (BorderLayout) with a grid of JButtons (the board) which works fines, a couple of panels on the side, and a panel at the bottom with 3 JButtons on it, which represent 3 tetris pieces.
The problem comes when I run the Client : I have a method that gets a pool of 3 pieces (and get the details on each one) when I launch the client, so I can get the name, the color, etc. to define the proper action when I clic on these JButtons.

public void setBoutons(Piece[] bloc)
{
this.piece1 = bloc[0];
this.piece2 = bloc[1];
this.piece3 = bloc[2];

this.nompiece1 = piece1.getNom();
this.nompiece2 = piece2.getNom();
this.nompiece3 = piece3.getNom();

//System.out.println(nompiece1);

this.bouton1.setActionCommand(this.nompiece1);
this.bouton2.setActionCommand(this.nompiece2);
this.bouton3.setActionCommand(this.nompiece3);

this.couleur1 = piece1.getCouleur();
this.couleur2 = piece2.getCouleur();
this.couleur3 = piece3.getCouleur();

this.disposition1 = piece1.getDisposition();
this.disposition2 = piece2.getDisposition();
this.disposition3 = piece3.getDisposition();

}


And what happens is that I can't set the ActionCommand. I tried many ways, even just using simple String like "hello" and I keep having this error :

Client exception: java.lang.NullPointerException
java.lang.NullPointerException
at Fenetre.setBoutons(Fenetre.java:174)
at Fenetre.<init>(Fenetre.java:60)
at Client.main(Client.java:22)


I put the whole code right below, except the actionPerformed part (takes a lot of space, if needed ask me for it) :

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Fenetre extends JFrame implements ActionListener{
private JButton[][] cases;
private JButton bouton1;
private JButton bouton2;
private JButton bouton3;
private String nompiece1;
private String nompiece2;
private String nompiece3;
private Color couleur1;
private Color couleur2;
private Color couleur3;
private byte[][] disposition1;
private byte[][] disposition2;
private byte[][] disposition3;
private Piece piece1;
private Piece piece2;
private Piece piece3;
private byte p1;
private byte p2;
private byte p3;
private Interface ninja;
private JPanel grille;
private JPanel zonepieces;
private JPanel zonedroite;
private JPanel zonehaut;
private JLabel pseudo;
private JLabel score;


public Fenetre(Interface uneinterface)
{
this.ninja = uneinterface;
try
{
Piece[] unpool = ninja.PoolPieces();
this.setBoutons(unpool);
}
catch (RemoteException e)
{
e.printStackTrace();
}

this.p1 = 0;
this.p2 = 0;
this.p3 = 0;

this.cases = new JButton[10][10];
this.grille = new JPanel();
this.zonepieces = new JPanel();
this.zonedroite = new JPanel();
this.zonehaut = new JPanel();
this.grille.setLayout(new GridLayout(10, 10, 2, 2));

for(int j = 0; j<10; j++)
{
for(int i = 0; i<10; i++)
{
this.cases[j][i] = new JButton(" ");
this.cases[j][i].addActionListener(this);
this.cases[j][i].setActionCommand(""+j+i);
this.cases[j][i].setBackground(Color.gray);
this.grille.add(cases[j][i]);
}
}

this.bouton1 = new JButton();
this.bouton1.addActionListener(this);
this.bouton1.setBackground(Color.WHITE);

this.bouton2 = new JButton();
this.bouton2.addActionListener(this);
this.bouton2.setBackground(Color.WHITE);

this.bouton3 = new JButton();
this.bouton3.addActionListener(this);
this.bouton3.setBackground(Color.WHITE);

this.zonepieces.setLayout(new FlowLayout());
this.zonepieces.add(bouton1);
this.zonepieces.add(bouton2);
this.zonepieces.add(bouton3);
this.pseudo = new JLabel("Pseudo");
this.zonehaut.add(pseudo);
this.score = new JLabel("Score");
this.zonedroite.add(score);

add(grille, BorderLayout.CENTER);
add(zonepieces, BorderLayout.SOUTH);
add(zonedroite, BorderLayout.EAST);
add(zonehaut, BorderLayout.NORTH);

this.setTitle("1010");
this.setSize(700, 700);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setVisible(true);

}

public void setBoutons(Piece[] bloc)
{
this.piece1 = bloc[0];
this.piece2 = bloc[1];
this.piece3 = bloc[2];

this.nompiece1 = piece1.getNom();
this.nompiece2 = piece2.getNom();
this.nompiece3 = piece3.getNom();

//System.out.println(nompiece1);

this.bouton1.setActionCommand(this.nompiece1);
this.bouton2.setActionCommand(this.nompiece2);
this.bouton3.setActionCommand(this.nompiece3);

this.couleur1 = piece1.getCouleur();
this.couleur2 = piece2.getCouleur();
this.couleur3 = piece3.getCouleur();

this.disposition1 = piece1.getDisposition();
this.disposition2 = piece2.getDisposition();
this.disposition3 = piece3.getDisposition();
}


Thanks in advance :)

Answer

In this constructor:

public Fenetre(Interface uneinterface) 
{
    this.ninja = uneinterface;
    try 
    {
        Piece[] unpool = ninja.PoolPieces();
        this.setBoutons(unpool);
    } 
    catch (RemoteException e) 
    {
        e.printStackTrace();
    }

you are calling the setBoutons method, which in turn accesses the bouton1 field. But that field is only initialized later in the constructor:

this.bouton1 = new JButton();

which means it's null at the point you are calling setBoutons. Change your constructor to initialize the boutons first and you should be fine.

In Java, all fields that have reference types (non-primitives) are null before they are initialized.