Ce chapitre complète le sujet du précédent en montrant comment créer un composant à partir d'un composant existant.
Ce chapitre décrira la création d'une case à cocher à trois états :
Base du composant.
La case à cocher sera basée sur un label (classe codice_1) pour afficher le texte, associé à une icône pour afficher l'état.
L'état du composant dépendra de l'état de la case, mais aussi du fait que la souris soit au-dessus du composant ou non.
Le tableau ci-dessous présente les différentes images utilisées, avec le nom du fichier utilisé par le code du composant pour charger l'image.
Téléchargez les images sous le nom indiqué, dans le répertoire du package de la classe.
État du composant.
Le composant a trois états possibles.
Contrairement à une case à cocher normale, le type booléen ne suffit plus à représenter l'état.
Il faut donc créer une énumération :
package org.wikibooks.fr.swing.component;
 * Trois états d'une case à cocher.
 * @author fr.wikibooks.org
public enum ETristate
 /** Non coché */
 UNCHECKED,
 /** Inconnu ou sélection partielle. */
 PARTIAL,
 /** Coché */
 CHECKED;
On ajoute deux méthodes retournant l'état suivant, selon deux modes de transition différents :
/**
 * Get next state in the following tri-state cycle: {@link #UNCHECKED} -> {@link #CHECKED} -> {@link #PARTIAL} -> {@link #UNCHECKED}.
 * @return The next state in the tri-state cycle.
 * @see #getNextDual()
public ETristate getNext()
 switch(this)
 case UNCHECKED: return CHECKED;
 case PARTIAL: return UNCHECKED;
 default: return PARTIAL;
 * Get next state in the following dual-state cycle: {@link #PARTIAL} -> {@link #UNCHECKED} -> {@link #CHECKED} -> {@link #UNCHECKED}.
 * @return The next state in the dual-state cycle.
 * @see #getNext()
public ETristate getNextDual()
 switch(this)
 case UNCHECKED: return CHECKED;
 default: return UNCHECKED;
Classe de la case à cocher.
Le code ci-dessous présente la première version de la classe du composant, complétée au fil des sections de ce chapitre.
La classe implémente l'interface codice_2 des objets contenant des éléments sélectionnables (la case à cocher elle-même).
package org.wikibooks.fr.swing.component;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
 * Case à cocher à trois états.
 * @author fr.wikibooks.org
public class TristateCheckbox extends JLabel
implements ItemSelectable
 private static Icon[] icons;
 static
 // Chargement des icônes représentant l'état de la case à cocher :
 icons = new Icon[6];
 for(int i=0,j=0;i<3;i++)
 icons[j++] = new ImageIcon(TristateCheckbox.class.getResource("checkbox_"+i+".png"));
 icons[j++] = new ImageIcon(TristateCheckbox.class.getResource("checkbox_"+i+"_over.png"));
 // L'état de la case à cocher
 protected ETristate state = ETristate.UNCHECKED;
 // Indicateur de souris survolant le composant, et de mode à deux ou trois états.
 protected boolean mouse_over = false, dual_state = false;
 private int i_state = 0; // Index de l'état courant
 // Écouteur d'évènements pour la case à cocher :
 ArrayList<ItemListener> ll_item = new ArrayList<ItemListener>();
 protected void fireItemEvent(boolean selected)
 ItemEvent e = new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
 this, selected ? ItemEvent.SELECTED : ItemEvent.DESELECTED);
 for(ItemListener l : ll_item)
 l.itemStateChanged(e);
 @Override
 public void addItemListener(ItemListener l)
 @Override
 public Object[] getSelectedObjects()
 @Override
 public void removeItemListener(ItemListener l)
// ... à compléter
Gestion de l'état du composant.
La méthode suivante est appelée par plusieurs autres méthodes pour mettre à jour l'icône affichée en fonction de l'état et des indicateurs de la case à cocher.
/**
 * Met à jour l'icône si nécessaire.
protected void updateState()
 int n = i_state;
 i_state = (mouse_over?1:0) | (state.ordinal()«1);
 if (i_state != n)
 setIcon(icons[i_state]);
 // Notifier les écouteurs enregistrés du changement d'état :
 fireItemEvent(state!=ETristate.UNCHECKED);
Elle est utilisée par exemple par la méthode modifiant l'indicateur de survol de la souris :
private void setMouseOver(boolean b)
 mouse_over = b;
 updateState();
Et également par les méthodes modifiant l'état de la case à cocher, en mode trois états ou en mode deux états.
 * Get the current checkbox state.
 * @return The current state.
public ETristate getState()
 return state;
// Définir l'état, en mode trois états
public void setState(ETristate state)
 this.state = state;
 this.dual_state = false;
 updateState();
// Définir l'état, en mode deux états
public void setDualState(ETristate state)
 this.state = state;
 this.dual_state = true;
 updateState();
// Définir l'état, en mode deux états, à moins que l'état soit inconnu/partiel
public void setMultipleState(ETristate state)
 this.state = state;
 this.dual_state = state != ETristate.PARTIAL;
 updateState();
La méthode codice_3 met la case à cocher dans l'état suivant, selon le mode de cycle courant.
protected void nextState()
 // Tester si le composant est activé, car cette méthode est appelée au clic de souris.
 if (isEnabled())
 state = dual_state ? state.getNextDual() : state.getNext();
 updateState();
Déclencher une action.
Beaucoup de composants Swing permettent de déclencher une action sur certains évènements.
Les méthodes ci-dessous fournissent une implémentation pour définir un nom d'action et enregistrer des écouteurs de déclenchement d'action.
protected String action_command = "";
public void setActionCommand(String action_command)
 this.action_command = action_command;
public String getActionCommand()
 return action_command;
ArrayList<ActionListener> ll_action = new ArrayList<ActionListener>();
public void addActionListener(ActionListener l)
 ll_action.add(l);
public void removeActionListener(ActionListener l)
 ll_action.remove(l);
protected void fireAction(String command, int modifiers)
 ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
 command, System.currentTimeMillis(), modifiers);
 for(ActionListener l : ll_action)
 l.actionPerformed(e);
Constructeurs.
Le constructeur de la case à cocher définit l'écouteur d'évènements de la souris qui appelle les méthodes vues précédemment.
// Constructeurs définissant des valeurs par défaut:
public TristateCheckbox()
public TristateCheckbox(String label)
public TristateCheckbox(int align)
// Contructeur principal
public TristateCheckbox(String label, int align)
 super(label, icons[0], align); // Non coché initialement
 setFocusable(true); // Peut obtenir le focus
 addMouseListener(new MouseListener()
 public void mouseReleased(MouseEvent e)
 // Vérifier que la souris survole encore le composant
 // au moment de relâcher le bouton.
 if (mouse_over) nextState();
 fireAction(action_command, e.getModifiersEx());
 public void mousePressed(MouseEvent e)
 setMouseOver(true);
 public void mouseExited(MouseEvent e)
 setMouseOver(false);
 public void mouseEntered(MouseEvent e)
 setMouseOver(true);
 public void mouseClicked(MouseEvent e)
 });
Test du composant.
Le code source pour tester la case à cocher est présenté ci-dessous :
// Méthode main utilisée pour tester le composant dans une fenêtre
public static void main(String[] args)
 // Créer la fenêtre
 JFrame f = new JFrame("Case à cocher");
 f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
 // Personnaliser le panneau du contenu
 JPanel p_content = new JPanel();
 p_content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
 p_content.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20));
 f.setContentPane(p_content);
 TristateCheckbox tcb = new TristateCheckbox("Test");
 p_content.add(tcb);
 f.pack();
 f.setVisible(true);

Agrodatabase/201 - Groupes de cultures
Pathologie/Pathologie diagnostique
La pathologie diagnostique est orientée sur la production de diagnostic.
Elle repose sur la pathologie spéciale et la pathologie chirurgicale. 
= Méthodes d'étude =