OVH Cloud OVH Cloud

NullPointerException avec isEnabled dans ButtonModel

2 réponses
Avatar
Bichounet
Bonjour,
J'aimerais utiliser un model pour gérer la proprité "Enabled" des boutons.
Voici la partie du code concernée :

class MyComponent extends JComponent
{
Timer timer = new Timer(1000,taskPerformer);
JButton startButton = new JButton("Start");

public boolean isRunning()
{
return timer.isRunning();
}

class startButtonModel extends DefaultButtonModel
{
public boolean isEnabled()
{
return isRunning() == false;
}
}

public MyComponent ()
{
startButton.setModel(new startButtonModel());
add(startButton);
}
};


Exception in thread "main" java.lang.NullPointerException
at MyComponent$startButtonModel.isEnabled(Unknown Source)
at javax.swing.DefaultButtonModel.setEnabled(Unknown Source)
at javax.swing.DefaultButtonModel.<init>(Unknown Source)
at MyComponent$startButtonModel.<init>(Unknown Source)
at MyComponent.<init>(Unknown Source)

Je crois comprendre que l'objet MyComponent n'est pas construit dans
startButtonModel.isEnabled().
En jetant un oeil dans les sources de DefaultButtonModel, je trouve :

public DefaultButtonModel() {
stateMask = 0;
setEnabled(true);
}

Le constructeur fait un setEnabled(true);
Et plus loin :

public void setEnabled(boolean b) {
if(isEnabled() == b) {
return;
}

if (b) {
stateMask |= ENABLED;
} else {
stateMask &= ~ENABLED;
// unarm and unpress, just in case
stateMask &= ~ARMED;
stateMask &= ~PRESSED;
}

fireStateChanged();
}

... je trouve l'appel à isEnabled(), que j'ai surchargé et qui fait appel au
timer de ma classe.

En surchangant setEnabled() dans mon ButtonModel pour supprimer
if(isEnabled() == b) {
return;
}

ca marche.

J'utilise le JDK 1.4.2_04.

Qu'en pensez-vous ??

Merci.

2 réponses

Avatar
Eric Frigot
Bichounet wrote:
Bonjour,
J'aimerais utiliser un model pour gérer la proprité "Enabled" des boutons.
Voici la partie du code concernée :

class MyComponent extends JComponent
{
Timer timer = new Timer(1000,taskPerformer);
JButton startButton = new JButton("Start");

public boolean isRunning()
{
return timer.isRunning();
}

class startButtonModel extends DefaultButtonModel
{
public boolean isEnabled()
{
return isRunning() == false;
}
}

public MyComponent ()
{
startButton.setModel(new startButtonModel());
add(startButton);
}
};


Exception in thread "main" java.lang.NullPointerException
at MyComponent$startButtonModel.isEnabled(Unknown Source)
at javax.swing.DefaultButtonModel.setEnabled(Unknown Source)
at javax.swing.DefaultButtonModel.<init>(Unknown Source)
at MyComponent$startButtonModel.<init>(Unknown Source)
at MyComponent.<init>(Unknown Source)

Je crois comprendre que l'objet MyComponent n'est pas construit dans
startButtonModel.isEnabled().
En jetant un oeil dans les sources de DefaultButtonModel, je trouve :

public DefaultButtonModel() {
stateMask = 0;
setEnabled(true);
}

Le constructeur fait un setEnabled(true);
Et plus loin :

public void setEnabled(boolean b) {
if(isEnabled() == b) {
return;
}

if (b) {
stateMask |= ENABLED;
} else {
stateMask &= ~ENABLED;
// unarm and unpress, just in case
stateMask &= ~ARMED;
stateMask &= ~PRESSED;
}

fireStateChanged();
}

... je trouve l'appel à isEnabled(), que j'ai surchargé et qui fait appel au
timer de ma classe.

En surchangant setEnabled() dans mon ButtonModel pour supprimer
if(isEnabled() == b) {
return;
}

ca marche.

J'utilise le JDK 1.4.2_04.

Qu'en pensez-vous ??

Merci.


J'ai rencontré le même problème il y a peu. Le problème c'est que tu
redéfinis une méthode de DefaultButtonModel. Or cette méthode est
apellée par le constructeur de DefaultButtonModel qui utilisera ton
implémentation de isEnabled() qui elle considère l'objet déjà construit.
Tu peux insérer un boolean qui t'indique que ton initialisation est faite :

class MyComponent extends JComponent
{
Timer timer = new Timer(1000,taskPerformer);
JButton startButton = new JButton("Start");

public boolean isRunning()
{
return timer.isRunning();
}

class startButtonModel extends DefaultButtonModel
{
boolean initialize = false;

public startButtonModel()
{
super();
initialize = true;
}

public boolean isEnabled()
{
if (this.initialize)
return isRunning() == false;
else
return super.isEnabled(); // sinon, celle du père
}
}

public MyComponent ()
{
startButton.setModel(new startButtonModel());
add(startButton);
}
};

Ah oui, un conseil, nommes plutot tes classes avec la première lettre en
majuscule.

Eric.

Avatar
Bichounet
Merci pour la réponse.
En fait je me demande plutôt si ce n'est pas une bêtise de faire

setEnabled(true);

dans le constructeur de DefaultButtonModel puisque c'est sujet à problème.
Si un bouton doit être "Enabled" à sa construction, pourquoi ne pas écrire
le constructeur de DefaultButtonModel comme ceci :

public DefaultButtonModel() {
stateMask = ENABLED;
}

et tout le monde est contant.

Xavier.