|
Le signe © renvoie à la correction |
On vous demande de réaliser une application pour compter (des bactéries sous le microscope, des passagers embarquant dans un bateau, des étoiles dans le ciel, etc.). Cela se présente (voyez la figure 1) comme un panneau comportant un titre, un nombre entier et un bouton. Chaque fois que lutilisateur appuie sur le bouton, le nombre augmente d’une unité. A. Pour commencer, réalisez un programme
très minimaliste : une classe Il vous faudra aussi une classe auxiliaire B. [Légère amélioration du code] Remplacez la classe interne AuditeurBouton par une classe anonyme. C. [Légère amélioration de laspect] Faites en sorte que le bouton « ++ » ait sa largeur préférée (voyez la figure 2), au lieu doccuper toute la largeur du cadre. Pour cela, intercalez un panneau entre le bouton et le cadre. D. [Grosse amélioration du code]
Faites les choses comme il faut les faire : réorganisez le
code précédent afin de définir une classe Pour essayer cette classe, écrivez une classe de test avec une méthode |
|
E. Pour vous convaincre du bien fondé
de cette manière d’organiser le code, modifiez la méthode main
précédente afin quelle crée un cadre avec, par exemple,
quatre compteurs indépendants :
Fig. 3
Lobjet de cet exercice est la réalisation dun composant Horloge
servant à afficher la date et lheure courantes
– rafraîchies toutes les secondes – dans une interface
graphique.
Un objet Horloge
doit pouvoir être utilisé
à tout endroit où un objet JLabel
peut être utilisé, et doit supporter les personnalisations (changement
de taille, de couleur, de police, etc.) que peut supporter un JLabel
(cette phrase devrait vous faire penser « héritage »).
Cette classe possédera un constructeur
public Horloge(String texte, String format)
où texte est la chaîne quon souhaite
voir affichée devant lheure et format une
chaîne spécifiant la présentation de lheure
(au besoin, revoyez lexercice 1.5 ou bien la classe SimpleDateFormat
). Par exemple, dans lillustration
ci-contre, texte
est la chaîne "Il
est"
et format
la chaîne "HH:mm:ss"
.
Dans cet exemple, un objet Horloge
a été
ajouté comme composant inférieur (« SOUTH
»)
dun cadre ayant par ailleurs une icône comme composant central.
L'horloge a été personnalisée pour avoir un premier plan rouge, un fond cyan et des caractères SansSerif
de 18 points.
Pour obtenir le rafraîchissement de lheure faites en sorte que
la construction dun objet Horloge
produise la mise
en route dun Thread
séparé, associé
à un objet Runnable
dont la méthode run
peut être ainsi décrite :
sleep
...)N.B. 1. On crée une instance de la classe Thread
en appelant un constructeur qui prend pour argument un objet Runnable
; on met en route le thread ainsi créé en appelant sa méthode start()
.
Un objet Runnable
est tout simplement un objet qui possède une méthode nommée public void run()
. Dans le présent exercice, l’objet Runnable
peut être lobjet Horloge
lui-même.
N.B. 2. Une icône (interface javax.swing.Icon
) est une image, souvent petite, utilisée pour décorer un élément de l’interface graphique. Par exemple, un JLabel
peut porter un texte, ou une icône, ou les deux.
Les objets « image icon » (classe javax.swing.ImageIcon
) sont des Icon
simples et pratiques quon crée à partir dun fichier, dune URL ou même dun tableau d'octets.
Un certain nombre de boîtes de dialogue simples sont utilisées très fréquemment dans toutes sortes dapplications : les boîtes dinformation (figure 2), les « questions » à deux et trois boutons (figure 3), la saisie dune chaîne, soit libre (figure 4), soit en la choisissant dans une liste de possibilités (figure 5).
En Java les boîtes de dialogue prêtes–à–lemploi sobtiennent très
facilement à laide des méthodes statiques |
|
Cela se présente comme un cadre contenant une colonne de boutons. La pression sur un bouton affiche la boîte de dialogue en question. Lorsque la chose est pertinente, linformation obtenue à travers la boîte de dialogue est affichée à laide dune boîte dinformation, pour contrôle.
Fig. 2 |
Fig. 3 |
Fig. 4 |
Fig. 5 |
Note. Observez la différence daspect des cadres et des boîtes
de dialogue que vous obtenez selon que vous avez ou non mis, avant toute création dun objet JFrame
ou JDialog
(les méthodes show...Dialog
créent de tels
objets) les deux lignes
JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true);
Comme plusieurs autres composants de Swing, les listes (classe Pour pratiquer cela nous allons réaliser une application qui construit et affiche on se contentera de cela, mais on pourrait imaginer des fonctions ultérieures dimpression, de sauvegarde dans un fichier, etc. une liste simple, par exemple la liste des courses au supermarché, voyez la figure ci-contre. Pour ajouter un item à cette liste il faut le taper dans le champ de texte tout en bas de linterface, puis actionner le bouton « Ajout ». Pour supprimer un item il faut le sélectionner dans la liste puis agir sur le bouton « Suppr ». A. Pour commencer ne vous occupez que de
linterface (c.-à-d. ignorez le comportement associé aux
composants). Écrivez une classe |
L’objet ListeSimple est géré par un BorderLayout , contenant : |
||
- comme composant central, un objet JScrollPane
qui contient à son tour un objet JList initialisé comme indiqué
plus loin, |
||
- comme composant inférieur, un objet JPanel
géré par un GridLayout à une
colonne (il en découlera 2 lignes), contenant |
||
- un JPanel géré par un GridLayout
à une ligne (il en découle 2 colonnes), contenant deux boutons "Ajout" et "Suppr" |
||
- un JTextArea |
Écrivez également une classe de test, avec une méthode main qui se
limite à créer un cadre (classe JFrame
)
et lui donner comme panneau de contenu un objet ListeSimple
.
B. Dans un deuxième temps intéressons-nous à la détection et au traitement des actions de lutilisateur sur cette interface.
Pour lutilisateur, les moyens daction principaux sont les deux boutons Ajout et Suppr. Or, lajout na de sens que si un mot est tapé dans la zone de texte ; de même, la suppression nest pertinente que si un item de la liste est sélectionné. On pourrait traiter ces « préconditions » par des tests placés à lentrée des fonction qui traitent les actions sur les boutons. Mais on préfère généralement, et cest ce que nous ferons ici, régler cela en amont de laction de lutilisateur, en désactivant (estompant) les boutons lorsque lopération quils expriment na pas de sens.
Pour une fois nous allons renoncer aux classes internes anonymes en déclarant
que notre classe ListeSimple
implémente les interfaces
ActionListener
, pour détecter les événements
sur les boutons (des pressions) ; cette interface comporte une unique méthode
actionPerformed(ActionEvent ae)
,ListSelectionListener
, pour détecter la sélection
ou la dé-sélection dun élément de la liste ;
cette interface comporte également une unique méthode valueChanged(ListSelectionEvent
lse)
,DocumentListener
, pour détecter les caractères
frappés ou effacés dans la zone de texte. Il sagit ici dune
interface à trois méthodes, changedUpdate(DocumentEvent
de)
, insertUpdate(DocumentEvent de)
et removeUpdate(DocumentEvent
de)
, dont seules les deux dernières nous intéressent.A divers endroits du constructeur de ListeSimple
nous aurons
donc les instructions
laListe.addListSelectionListener(this); zoneTexte.getDocument().addDocumentListener(this); boutonAjout.addActionListener(this); boutonSuppr.addActionListener(this);
Écrivez les méthodes mentionnées plus haut, qui donnent
à notre interface le comportement voulu. Les méthodes valueChanged
(de ListSelectionListener
), insertUpdate
et removeUpdate
(de DocumentListener
)
se chargent d« allumer » et d« éteindre »
les boutons, la méthode actionPerformed
de ActionListener
soccupe de faire le travail dajout ou de suppression dun élément.
On vous demande décrire un éditeur de textes simple, analogue au bloc-notes de Windows :
Fondamentalement, le bloc notes est un cadre (classe JFrame
)
avec une barre de menus (classe JMenuBar
) et un panneau
de contenu dans lequel on aura mis un panneau de défilement (classe JScrollPane
)
contenant une zone de texte (classe JTextArea
).
On veillera à ce que toute commande produisant la perte du texte édité soit précédée dune confirmation :
Le menu Fichier est formé des commandes les plus classiques
Le menu Aide se réduit à la boîte à propos :
Note 1. Pour déterminer sil y a lieu de demander une confirmation avant
de détruire le texte définissez une variable dinstance texteModifié
que certaines opérations mettent à false
,
et qui est mise à true chaque fois quun caractère
est tapé au clavier en visant la zone de texte (événement
Key
).
Note 2. La sauvegarde du texte dans un fichier ne pose pas de problème :
il suffit décrire tout le contenu de la zone de texte dans un FileWriter
ouvert à partir dun objet File
obtenu à laide
dun dialogue FileChooser
:
La lecture du texte est un peu plus alambiquée, car les objets FileReader
ne peuvent lire que dans un tampon de caractères, quil faudra allouer
à partir de la taille donnée par une expression de la forme unFichier.length()
(où unFichier est un objet File
obtenu à
laide dun objet FileChooser).
Vous voulez épater votre petit neveu, qui vous tient pour un héros, en lui montrant une section de spline cubique, cest-à-dire un segment de courbe définie par un polynôme de degré 3 dont les extrémités sont données et les tangentes aux extrémités aussi (voyez la figure 2). Cela tombe bien, de telles courbes sont prêtes à lemploi, disponibles dans la bibliothèque Java2D.
Le plus dur à faire sera de mettre en place un panneau portant quatre points (les deux extrémités de la courbe et les deux extrémités restantes des tangentes) quon pourra déplacer avec la souris pour observer les changements de la courbe.
A. Définissez la classe Cubique
,
sous-classe de JPanel
, qui représente un panneau
montrant quatre points, extrémités de deux segments, voyez la
figure 1. A la création ces points ont des positions convenues, ensuite
lutilisateur peut les attraper avec la souris et les déplacer comme
il veut.
Indications. Définissez une classe interne pour représenter
les points, chacun ayant sa propre couleur. Un Point
est
fait de trois variables dinstance, deux (x
et y
)
de type int
et une de type Color
. Votre classe Cubique
contiendra comme variable dinstance un tableau
de quatre de tels objets.
Fig. 1
La méthode void paint(Graphics g)
de votre classe Cubique
consistera essentiellement à tracer les
deux segments (méthode drawLine
) puis à
dessiner les quatre points sous forme de petits carrés (méthode fillRect
).
Pour le déplacement des points à la souris déclarez que
votre classe implémente les interfaces MouseListener
et MouseMotionListener
. Cela vous oblige à écrire
sept méthodes, dont seules trois vous intéressent :
mousePressed
- lorsque cet événement se
produit, il faut chercher le point près duquel on a cliqué et
en faire la valeur dune certaine variable dinstance pointSélectionnémouseDragged
- si pointSélectionné
nest pas null
, il faut lui donner pour coordonnées
celles de lévénement souris, et redessiner le panneaumouseReleased
- ici il suffit de remettre pointSélectionné
à null
.B. Pour montrer la spline cubique définie
par les quatre points (les noirs jouent le rôle dextrémités
de la courbe, les rouges définissent les tangentes) il faut déclarer
une variabe dinstance de type CubicCurve2D.Double, créée
lors de la construction du panneau et, surtout, positionnée à
chaque appel de la méthode paint par un appel de la
méthode setCurve
. Cette méthode requiert quatre
objets de type Point2D.Double
(des points aux coordonnées double
) quil faudra construire à partir des
coordonnées (entières) des quatre points dessinés.
Fig. 2
A. Lobjet de lexercice est lécriture dune classe simple effectuant la représentation graphique dune fonction réelle dune variable réelle. Par exemple, dans le cas de la fonction y = sin x :
Fig. 1
La fonction est traceé de manière à remplir au mieux le panneau de dessin. Ainsi, les modifications de la taille ou de la forme du cadre entraînent un nouveau tracé, voyez la figure 2.
Écrivez une classe Traceur
, sous-classe de JPanel
.
Elle est munie dun constructeur
oùpublic Traceur(Fonction fonc);
Fonction
est une interface ainsi définie :
public interface Fonction { double tion(double x); double xMin(); double xMax(); }
Par exemple, le tracé montré sur les figures 1 et 2 est
obtenu en construisant un panneau Traceur panneau = new Traceur(new Fonction() { public double tion(double x) { return Math.sin(x); } public double xMin() { return -10; } public double xMax() { return 10; } }); |
Fig. 2 |
A partir des valeurs renvoyées par xMin()
et
xMax()
le constructeur calcule les valeurs de yMin
et yMax
, ces quatre valeurs sont conservées dans
des variables dinstance privée.
Le tracé lui-même est pris en charge par la rédéfinition
de la méthode canonique paint(Graphics g)
, qui commence
par obtenir la taille du panneau (méthode getSize()
)
et en déduire les quatre coefficients Ax,
Bx, Ay
et By permettant de convertir les coordonnées
« utilisateur » (xu,
yu) en des coordonnées «
écran » (xe, ye) :
xe = Ax × xu + Bx
ye = Ay × yu + By
Notez que xu et yu
sont des double
, alors que xe
et ye sont des int
.
Si le cœur vous en dit, pour pouvez compléter ce programme par le tracé dun quadrillage ou laffichage de repères numériques..
B. Ajoutez au programme précédent la possibilité de « zoomer » sur une partie du tracé : lorsque lutilisateur définit un rectangle avec la souris (par les gestes habituels : presser le bouton, déplacer la souris, relâcher le bouton) les coefficients Ax, Bx, Ay et By sont recalculés afin que la partie du tracé délimitée par ce rectangle remplisse tout le panneau.
On doit pouvoir revenir en arrière. Par exemple, si lutilisateur fait un « Ctrl-clic » nimporte où dans le panneau, le tracé doit reprendre ses proportions précédentes.