Reputation: 27
in this code i have a jbutton with an ActionListener added to it (BoutonListener) but when the button is clicked, the method actionPerformed() is never called. I'm new with SWING so i'm might have overlooked something important, but i don't what i missed here, help please.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.util.*;
public class Plateau{
Fenetre f;
Modele mo;
CaseListener co;
BoutonListener li;
public Plateau(int dim){
this.f = new Fenetre(dim);
this.mo = new Modele();
this.co = new CaseListener();
this.li = new BoutonListener();
}
private class Fenetre extends JFrame{
public JPanel principale; // partie informative
public JPanel grille; // grille de jeu
public Case [][] tabs;
public int dim;
private static final String bf1 = "bf1.png";
private static final String mf1 = "mf1.png";
private static final String nf1 = "nf1.png";
private static final String bf2 = "bf2.png";
private static final String mf2 = "mf2.png";
private static final String nf2 = "nf2.png";
Container c = this.getContentPane();
JButton b = new JButton("bon"); // boutons pour ajouter les fantomes
JButton m = new JButton("mauvais");
public Fenetre(int dim){
this.dim = dim;
this.tabs = new Case[this.dim][this.dim];
c.setLayout(new GridLayout(0,2));
JPanel principale = new JPanel();
JPanel grille = new JPanel();
JLabel lab = new JLabel("Test");
principale.add(lab);
b.addActionListener(li);
m.addActionListener(li);
principale.add(b);
principale.add(m);
c.add(principale);
grille.setBackground(Color.black);
c.add(grille);
this.setVisible(true);
this.setSize(600,300);
this.setLocationRelativeTo(null);
this.setTitle("Ghosts");
grille.setLayout(new GridLayout(this.dim, this.dim));
for(int i = 0; i < this.dim ; i++){
for(int j = 0; j < this.dim ; j++){
// création de toutes les cases
tabs[i][j] = new Case();
tabs[i][j].addMouseListener(co);
tabs[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
grille.add(tabs[i][j]);
if( (i == 0 || i == this.dim-1) && ( j == 0 || j == this.dim-1 )){ // cases sorties
tabs[i][j].setBackground(Color.BLUE);
}
}
}
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void miseAJour(){
for(int i = 0 ; i < this.dim ; i++){
for(int j = 0 ; j < this.dim ; j++){
tabs[i][j].repaint();
}
}
}
}
private class Modele{
int total = 0;
int bj1 = 0;
int mj1 = 0;
int bj2 = 0;
int mj2 = 0;
public Case prochainePlace(){
for(int i = 0; i < f.dim ; i++){
for(int j = 0; j < f.dim ; j++){
if(j !=0 && j != f.dim - 1 && (i > f.dim-3 || (i < 2)) ){ // fantomes J1
if(f.tabs[i][j].getFantome() == null){
total++;
return f.tabs[i][j];
}
}
}
}
return null;
}
public boolean remplissable(){
return((bj1 + bj2 + mj1 + mj2) < (f.dim *2)-4 );
}
public void ajoutFantome(Case c , boolean bon){
if(total <= 8){
if(bon && bj1 < 4){
c.setFantome(new Fantome(true, Fenetre.bf1 , 2 ));
c.repaint();
bj1++;
}
if(!bon && mj1 < 4){
c.setFantome(new Fantome(false,Fenetre.mf1 , 1 ));
c.repaint();
mj1++;
}
}
else{
if(bon && bj2 < 4 ){
c.setFantome(new Fantome(true, Fenetre.bf2 , 2 ));
c.repaint();
bj2++;
}
if(!bon && mj2 < 4){
c.setFantome(new Fantome(false, Fenetre.mf2 , 2 ));
c.repaint();
mj2++;
}
}
}
}
private class BoutonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
System.out.println("fonction called");
if(mo.remplissable()){
if(e.getSource() == f.b){
mo.ajoutFantome(mo.prochainePlace(), true);
f.miseAJour();
}
else{
mo.ajoutFantome(mo.prochainePlace(), false);
f.miseAJour();
}
}
}
}
private class CaseListener implements MouseListener{
public void mouseClicked(MouseEvent e){
}
public void mouseExited(MouseEvent e){
}
public void mousePressed(MouseEvent e){
}
public void mouseReleased(MouseEvent e){
}
public void mouseEntered(MouseEvent e){
}
}
}
Upvotes: 0
Views: 226
Reputation: 285403
Note your Plateaue constructor:
public Plateau(int dim) {
this.f = new Fenetre(dim); // (A)
this.mo = new Modele();
this.li = new BoutonListener(); // (B)
}
You create your Fenetre JFrame at line (A), and this is where you add your ActionListener, li, to the JButtons, but you assign an ActionListener to the li variable at (B) after you've created the JFrame. So you're really adding null references as ActionListeners to the JButtons with in your Fenetre constructor:
public Fenetre(int dim) {
// .... <deleted code>
// li is null here!
b.addActionListener(li);
m.addActionListener(li);
One Solution: Reverse this.
public Plateau(int dim) {
this.li = new BoutonListener(); // call this first
this.f = new Fenetre(dim);
this.mo = new Modele();
}
Now the JButtons will get ActionListeners instances and not null references.
Note, a better more OOP-compliant solution might be to give Fenetre its own addBoutonListener(ActionListener l)
method, one where you add the listeners to the JButtons, so that your Plateau constructor code could instead be:
public Plateau(int dim) {
this.f = new Fenetre(dim);
this.mo = new Modele();
f.addBoutonListener(new BoutonListener());
}
And within Fenetre, you could have:
public void addBoutonListener(BoutonListener btnListener) {
b.addActionListener(btnListener);
m.addActionListener(btnListener);
}
Upvotes: 3