Intercepter des frappes composées de touches et
utiliser des polices de caractères
alt : l'applet n'est pas visible par votre
navigateur (dans le menu Outils, Modules complémentaires,
activer le plugin Java(TM) Platform SE 6 U32 6.0.320.5 s'il est
désactivé)
Le bouton droit est le bouton droit de la souris.
On peut intercepter comme nous l'avons vu dans l'exemple
précédent les frappes sur les touches
alphabétiques ou numériques. On peut aussi
intercepter l'utilisation d'associations de ces touches avec des
touches modificatrices ("ctrl", "shift", "meta" et "alt"ctrl) ou avec
les boutons enfoncés de la souris. Toutes les touches du
clavier peuvent aussi être utilisées, en
particulier les touches de fonction ; les touches sont
identifiées par des constantes analogues à celles
que vous pouvez voir dans le code de notre exemple (VK_R pour le r...,
VK_BACK_SPACE, VK_TAB, VK_COMMA, VK_F3, VK_UP, VK_PAGE_UP, VK_HOME,
VK_ESCAPE...) ; vous pouvez consulter l'ensemble de ces constantes dans
la documentation de la classe java.awt.event.KeyEvent .
Voici une illustration donnant
quelques précisions teminologiques en anglais concernant
diférentes mesures liées aux polices de
caractères.
Le "leading" correspond à un simple interligne. Les
méthodes getHeight ,getLeading ,
getAscent et getDescent de
la classe java.awt.FontMetrics permettent de
connaître les valeurs correspondantes ; la méthode
getSize() de la classe java.awt.Font
permet de retrouver la taille de la police.
On aurait pu aussi utiliser un JTextArea
ou des JLabel (s) pour la liste des indications ;
ce serait en fait plus simple que d'utiliser la méthode drawString
comme on le fait ci-dessous. On donne après le code
ci-dessous des programmes correspondant à ce deux autres
solutions.
Voici un programme correspondant
à l'applet que vous pouvez apercevoir.
import javax.swing.JPanel;import javax.swing.JFrame;import javax.swing.JLabel;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Graphics;import java.awt.Dimension;import java.awt.event.KeyListener;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.awt.Font;import java.awt.FontMetrics;import java.awt.event.InputEvent;class Indication extends JPanel { int h; Indication() { int hauteur, largeur; Font font = new Font("TimesRoman", Font.BOLD|Font.ITALIC,14); FontMetrics ft = getFontMetrics(font); h = ft.getHeight() ; largeur = ft.stringWidth("bouton gauche + b pour voir un disque bleu "); setPreferredSize(new Dimension(largeur, 6*h + 25)); setFont(font); } public void paintComponent(Graphics g) { int x = 10, y = 40; g.drawString(" r pour voir un cercle rouge", x, y); y += h; g.drawString(" CTRL + r pour voir un disque rouge", x, y); y += h; g.drawString(" b pour voir un cercle bleu", x, y); y += h; g.drawString(" bouton droit + b pour voir un disque bleu", x, y); y += h; g.drawString(" barre d'espace pour descendre le cercle", x, y); y += h; g.drawString(" touche \"arriere\" pour repositionner le cercle", x, y); } }class Ardoise extends JPanel { private Color couleur = Color.BLUE; private boolean plein = false; private int hauteur = 20; Ardoise() { setPreferredSize(new Dimension(250, 200)); } public void paintComponent(Graphics g) { int largeur = getSize().width; super .paintComponent(g); g.setColor(couleur); if (plein) g.fillOval((largeur - 100)/2, hauteur, 100, 100); else g.drawOval((largeur - 100)/2, hauteur, 100, 100); } void setCouleur(Color couleur) { this .couleur = couleur; repaint(); } void setPlein(boolean valeur) { plein = valeur; repaint(); } void setHauteur(int valeur) { hauteur = valeur; repaint(); } }public class Touches2 extends JFrame implements KeyListener { Ardoise ardoise = new Ardoise(); Touches2() { super ("Essai des touches"); add(new Indication(), BorderLayout.NORTH); add(ardoise, BorderLayout.CENTER); addKeyListener(this ); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowOpened(WindowEvent e) { requestFocus(); } }); pack(); setVisible(true ); } public void keyPressed(KeyEvent evt) { int code = evt.getKeyCode(); if (code == KeyEvent.VK_R) { ardoise.setCouleur(Color.RED); if (evt.isControlDown() ) ardoise.setPlein(true ); else ardoise.setPlein(false ); } else if (code == KeyEvent.VK_B) { ardoise.setCouleur(Color.BLUE); if ((evt.getModifiersEx() & InputEvent.BUTTON3_DOWN_MASK) != 0) ardoise.setPlein(true ); else ardoise.setPlein(false ); } else if (code == KeyEvent.VK_SPACE) ardoise.setHauteur(80); else if (code == KeyEvent.VK_BACK_SPACE) ardoise.setHauteur(20); } public void keyTyped(KeyEvent evt) {} public void keyReleased(KeyEvent evt) {} }class EssaiTouches2 { public static void main(String[] arg) { new Touches2(); } }
Vous pouvez voir :
le code
en java l'application que vous voyez aussi sur cette page.
le code
de l'applet.
le code
en java l'application en utilisant un JTextArea .
le code
en java l'application en utilisant des JLabel (s).
FontMetrics ft
= getFontMetrics(font) : cette méthode
de la classe Component permet de prendre
différentes mesures sur la police de caractères
indiquée en paramètre.
ft.getHeight()
: cette méthode de la classe FontMetrics
donne la hauteur nécessaire entre une ligne et la ligne
suivante.
ft.stringWidth("bouton
gauche + b pour voir un disque bleu "); : permet
de mesurer le nombre de pixels nécessaire en largeur pour
écrire, avec la fonte ft , la
chaîne de caractères indiquée en
paramètre.
evt.isControlDown()
: méthode de la classe abstraite java.awt.event.InputEvent
dont hérite la classe keyEvent qui
retourne true ou false
selon que la touche "ctrl" est enfoncée ou non.
evt.getModifiersEx()
: méthode de la classe InputEvent
(qui, améliore la méthode getModifiers ),
dont héritent les classes KeyEvent et MouseEvent ,
qui renvoie un int
décrivant les touches de modification (parmi "ctrl",
"shift", "meta", "alt", "alt graph") et les boutons de la souris
éventuellement utilisés. À chacune de
ces touches ou chacun de ces boutons correspond une constante qui est
une puissance de 2 ; l'entier renvoyé par la
méthode getModifiersEx est la somme
des constantes correspondant aux touches ou boutons appuyés.
Supposons que l'utilisateur appuie à la fois sur le bouton
de droite de la souris et sur la touche "ctrl" (touche de
contrôle) ; au bouton droit de la souris correspond la
constante InputEvent.BUTTON3_DOWN_MASK qui vaut
4096 (écriture binaire 1000000000000) ; à la
touche "ctrl" correspond la constante InputEvent.CTRL_DOWN_MASK
qui vaut 128 (écriture binaire 10000000) ; la
méthode getModifiersEx renvoie dans
notre cas la somme de 4096 et de 128, c'est- à-dire 4224,
qui s'écrit 1000010000000 en binaire : un "1" pour le bouton
de droite de la souris et un "1" pour la touche "ctrl".
InputEvent.BUTTON3_DOWN_MASK
: : cette constante fait partie d'un ensemble de constantes
où on trouve aussi BUTTON1_DOWN_MASK , BUTTON2_DOWN_MASK ,
SHIFT_DOWN_MASK , CTRL_DOWN_MASK ,
ALT_DOWN_MASK , ALT_DOWN_GRAPH_MASK .
Considérons l'expression :
evt.getModifiersEx()
& InputEvent.BUTTON3_DOWN_MASK ;
Rappelons que la constante BUTTON3_DOWN_MASK vaut
4096. L'opérateur "& " est un
"et" bit à bit ; il faut pour l'évaluer
écrire les deux opérandes en binaire ; si, comme
dans l'exemple ci-dessus, on a appuyé sur le bouton droit de
la souris et sur la touche de contrôle, le calcul
effectué est : 1000010000000 & 1000000000000, dont
la valeur écrite en binaire est 1000000000000, et donc non
nulle. Le résultat est non nul si et seulement si on appuie
sur le bouton droit de la souris.
© Irène
Charon, Télécom-ParisTech 2011