La classe l'objet et le dessin
Cette feuille en Postscript

On peut décrire grossièrement les objets de l'Abstract Window Toolkit de Java ainsi. On peut noter que les classes Component et Container sont abstraites.

1  Interprétation

  1. Peut-on avoir des conteneurs de conteneurs ?
  2. La méthode paint prend en argument un contexte graphique Graphics dans lequel on peut dessiner par les méthodes idoines. Que représenet ce contexte, et pourquoi repaint ne prend-elle pas d'argument ?
  3. Que fait probablement la méthode repaint d'un conteneur ?
  4. Cela a-t-il un sens de mettre plusieurs cadres dans un conteneur ? Discuter typage et comportement à l'exécution.
Solution.

2  Salade d'étiquettes

Voici le programme graphique minimal :
import java.awt.* ;

class Minimal {
  
public static void main(String [] arg) {
    
Frame f = new Frame(arg[0]) ;
    f.show() ;
  }
}
  1. Que fait le programme graphique minimal ?

  2. Que va-t-il se passer si on fait « java Minimal ». Corriger un éventuel problème.

  3. Sur ma machine les valeurs par défaut du positionement et de la taille de la fenêtre du programme minimal ne sont pas satisfaisantes. Comment, à votre avis, contrôler la taille et le positionement de la fenêtre du programme minimal ?

  4. Le composant graphique tout prêt le plus simple est l'étiquette, Label, qui affiche juste la chaîne passée en argument au constructeur. Écrire la classe Salut dont les objets sont des fenêtres qui disent bonjour.

  5. On peut changer la couleur du fond d'un composant par la méthode setBackgroup(Color c), où les couleurs sont du style Color.red, Color.white etc. Concevoir, par héritage de la classe Label une classe des étiquettes au fond colorié.

  6. Tous les conteneurs possèdent un LayoutManager qui règle le positionnement relatif de leurs composants. Le conteneur le plus simple est le Panel et son LayoutManager est par défaut un FlowLayout qui affiche ses composants les uns à la suite des autres, d'abord de gauche à droite, puis sur une nouvelle ligne en cas de débordement. Écrire la classe Simple qui produit cette fenêtre
        
    La fenêtre est montrée dans deux tailles différentes, c'est le FlowLayout qui gère la répartition des boutons de cette façon, un peu comme des lignes de texte centrées.
Solution.

3  Salade de boutons

Le bouton est un composant assez simple, il se présente un peu comme l'étiquette mais peut en plus être solicité à la souris. Le bouton réagit à une solicitation en appelant la méthode actionPerformed de ses ActionListener. Ceux-ci sont enregistrés au préalable par la méthode addActionListener (du bouton). Ainsi le bouton mininal est :
import java.awt.* ;
import java.awt.event.* ;

class MinimalButton extends Button {
  
MinimalButton () {
    
super("Minimal") ;
    addActionListener(
new Minimal ()) ;
  }
}

class Minimal implements ActionListener {

  
public void actionPerformed (ActionEvent e) {
    System.err.println("Bouton solicité") ;
  }
}
  1. Concevoir la classe QuitButton des boutons qui servent à quiter une application.

  2. On se donne la classe Counter des compteurs.
    class Counter {
      
    private int n ;

      
    Counter(int n) { this.n = n ; }
      
    void incr() { n++ ; }
      
    void decr() { n-- ; }
      
    int get() { return n ; }
      
    public String toString() {return Integer.toString(n) ; }

    }
    Concevoir et réaliser un composant GraphicCounter qui, une fois ajouté à un Frame quelconque, donnera ce résultat.
    Étant entendu que cliquer sur « + » incrémente le compteur, que cliquer sur « - » le décrémente, et que le contenu courant du compteur est affiché. On procédera par étapes :
    1. Trouver une classe dont GraphicCounter peut être une sous classe.
    2. Concevoir et écrire le constructeur de cette classe.
    3. Se préocuper des ActionListener. Un démarche excessivement objet est de concevoir une classe abstraite des espions de nos deux boutons regroupant ce que ces espions ont de commun. On peut changer le texte affiché dans un Label par sa méthode setText(String txt).
    4. Donner le code qui ajoute notre compteur graphique à la fenêtre quelconque, comme par exemple, la méthode main de la classe GraphicCounter.


  3. Ajouter un bouton pour quitter. Ce bouton sera ajouté à la fenêtre quelconque. Le LayoutManager par défaut des Frame gère cinq zones, à savoir quatre bordures désignées par les quatre points cardinaux ("North", etc.), et une zone centrale ("Center"). Sa méthode add prend une chaîne désignant la zone en premier argument. L'effet recherché est celui-ci :
Solution.

4  Un composant très graphique

Le composant le plus simple est le canevas Canvas. Il correspond à un rectange dans lequel la méthode paint dessinera. Voici un canevas dont la méthode paint dessine le triangle de Sierpinsky à l'ordre donné par le contenu d'un compteur.
import java.awt.* ;

class SiepCanvas extends Canvas {
  
private Counter c ;

  
SiepCanvas(Counter c) {
    
super() ;
    
this.c = c;
  }

  
public void paint(Graphics g) {
    
int w = getSize().width ;
    
int h = getSize().height ;

    
Point top = new Point(w/2,0) ;
    
Point left = new Point(0,h) ;
    
Point right = new Point(w,h) ;
    
// effectivement dessiner par une méthode non-donnée.
    paintSiep(g, c.get() , top, left, right) ;
  }
}
Pour les curieux, la classe SiepCanvas complète et un beau dessin :
  1. On suppose que notre SiepCanvas est dans un Frame quelconque. À votre avis, que se passe-t-il lorsque que je redimensionne la fenêtre à la souris.

  2. Écrire une application graphique qui va présenter, de haut en bas, un compteur graphique, un triangle de Sierpinsky, et enfin un bouton pour quitter.

  3. Clique sur « + » ou « - » entraîne-t-il, à votre avis, l'affichage d'un nouveau triangle ? Si non, tenter d'y remédier avec les moyens du bord, mais en écrivant un minimum de code. L'héritage de Counter est suggéré.

  4. Résoudre le même problème en utilisant le style des ActionListener. Du point de vue de la class GraphicCounter cela demande d'ajouter une méthode addActionListener à la classe GraphicCounter, afin d'enregistrer l'espion, et d'invoquer l'espion chaque fois que l'un des boutons du compteur graphique est solicité. Noter que la construction des espions Plus et Moins par héritage facilite un peu cette dernière modification.
Solution.


Ce document a été traduit de LATEX par HEVEA et HACHA.