C. Recanati
IG, Java Swing
Info2, 2008

TP 7-8

Exercice 1
Ecrire une classe MonBouton qui étend JButton et définit un type de bouton qui modifie le curseur de souris quand elle entre sur le bouton. Tester votre classe (en définissant par exemple une classe BoutonCurseur étendant JFrame, dont le panneau de contenu contiendra un MonBouton).
  Pour créer un curseur de souris, on peut utiliser les constantes de la classe Cursor (cf. cours p. 241).
    On peut sélectionner les entrées/sorties de la souris sur le bouton en définissant le bouton comme étant son propre écouteur de souris (MouseListener). Pour définir cet écouteur, on peut utiliser une classe interne de type Adapter (une classe qui étend MouseAdapter) que l’on instanciera par new au moment de l’enregistrement de l’écouteur.
      Pour affecter le curseur, on peut utiliser getSource() qui retourne l’object source de l’événement (ici un MouseEvent) et ainsi écrire 
((Component) e.getSource()).setCursor(handCursor)
ou encore utiliser getComponent() - héritée de ComponentEvent  qui retourne directement la source comme Component.

Exercice 2 (suite du programme Sketcher, exercice 2 du TP précédent).
Rappel : On a créé une zone de texte sous une barre de menus qui comporte trois menus : Fichier, Elements et Aide. Pour cet exercice, on va afficher dans cette zone des informations sur l’origine des événements se produisant quand on actionne les items des menus. 
1) Implémenter l’interface ActionListener sur le cadre fenêtre pour traiter l’affichage des événements survenant lors de la sélection des items du menu Fichier.
 On pourra utiliser la procédure suivante pour l’affichage des informations :
    // Returne juste le nom de la classe – sans les packages (cf. TP1)
	protected String getClassName(Object o) {
		String classString = o.getClass().getName();
		int dotIndex = classString.lastIndexOf(".");
		return classString.substring(dotIndex+1);
	}

2) Même question en rajoutant l’interface ItemListener pour traiter la sélection des items du sous-menu « couleurs » de Elements. 

Eléments de correction
Exercice 1
// BoutonCurseur.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class BoutonCurseur extends JFrame {
   
	public BoutonCurseur() {
		getContentPane().add(new MonBouton ("Essai de \Curseur"));
	}
    
	public class MonBouton extends JButton {
        
		public MonBouton(String titre){
			super(titre);
			this.addMouseListener(new MouseHandler());
		}
        
		class MouseHandler extends MouseAdapter {
			Cursor handCursor = new Cursor
							(Cursor.HAND_CURSOR);
			Cursor defaultCursor = new Cursor
							(Cursor.DEFAULT_CURSOR);
			public void mouseEntered(MouseEvent e) {
				e.getSource()).setCursor(handCursor);
			}
			public void mouseExited(MouseEvent e) {
			   e.getComponent().setCursor(defaultCursor);
			}
		} // fin de la classe MouseHandler
	}	// fin de la classe interne MonBouton
    
	public static void main(String args[]) {
		BoutonCurseur window = new BoutonCurseur();

		window.setTitle("Bouton + Curseur");
		window.setDefaultCloseOperation
							(JFrame.EXIT_ON_CLOSE);
		window.setBounds(100, 200, 300, 200);
		window.setVisible(true);
	}
}

Exercice 2 :
// fichier SketcherFrame.java : on rajoute les lignes en gras
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SketcherFrame extends JFrame 
		    implements ActionListener,ItemListener {
                      
    protected JTextArea output;		// la zone de texte
    protected JScrollPane scrollPane;
    private JMenuBar menuBar; 	
    String newline = "\n";
        
    public SketcherFrame(String titre) {

		JMenu menu, submenu; 
		JMenuItem menuItem;
		JRadioButtonMenuItem rbMenuItem;
		JCheckBoxMenuItem cbMenuItem;

	setTitle(titre);
	setDefaultCloseOperation(EXIT_ON_CLOSE);

		// Créer le texte
	output = new JTextArea(10, 80);
	output.setEditable(false);
	scrollPane = new JScrollPane(output); 

		//Ajouter les composants 
	Container contentPane = getContentPane();
	contentPane.add(toolBar, BorderLayout.NORTH);
	contentPane.add(scrollPane, BorderLayout.CENTER);

		//Ajouter une barre de menu
	menuBar = new JMenuBar();
	setJMenuBar(menuBar);

		//Construire le menu Fichier
	menu = new JMenu("Fichier");
	menu.setMnemonic(KeyEvent.VK_F);

		//les items de Fichier
	menuItem = new JMenuItem("Ouvrir", KeyEvent.VK_O);
	menuItem.setAccelerator(KeyStroke.getKeyStroke(
							KeyEvent.VK_1,	
							ActionEvent.ALT_MASK));
	menuItem.addActionListener(this);
	menu.add(menuItem);

	menuItem = new JMenuItem		
				("A la fois texte et icone", 
                        new ImageIcon("images/middle.gif"));
	menuItem.setMnemonic(KeyEvent.VK_A);
	menuItem.addActionListener(this);
	menu.add(menuItem);

	menuItem = new JMenuItem(new 
					ImageIcon("images/middle.gif"));
	menuItem.setMnemonic(KeyEvent.VK_B);
	menuItem.addActionListener(this);
	menu.add(menuItem);

	menu.addSeparator();		// le séparateur

	menuItem = new JMenuItem("Enregistrer",
                                 KeyEvent.VK_E);
	menuItem.setAccelerator(KeyStroke.getKeyStroke(
							KeyEvent.VK_2,
							ActionEvent.ALT_MASK));
	menuItem.addActionListener(this);
	menu.add(menuItem);
        
		// Construire le second menu : Elements
	menu = new JMenu("Elements");
	menu.setMnemonic(KeyEvent.VK_E);
	menuBar.add(menu);

		//un groupe pour ses boutons radio 
	ButtonGroup group = new ButtonGroup();

	rbMenuItem = new JRadioButtonMenuItem("Ligne", true);
	rbMenuItem.setMnemonic(KeyEvent.VK_L);
	rbMenuItem.addActionListener(this);
	group.add(rbMenuItem);
	menu.add(rbMenuItem);

	rbMenuItem = new JRadioButtonMenuItem("Rectangle", 										false);
	rbMenuItem.setMnemonic(KeyEvent.VK_R);
	rbMenuItem.addActionListener(this);
	group.add(rbMenuItem);
	menu.add(rbMenuItem);

	// … ibid pour CERCLE, etc.
	menu.addSeparator();	

		// le sous-menu des cases couleurs
	submenu = new JMenu("Couleur");
	submenu.setMnemonic(KeyEvent.VK_C);
	ButtonGroup group2 = new ButtonGroup();

	cbMenuItem = new JCheckBoxMenuItem("Rouge", true) ;
	cbMenuItem.setMnemonic(KeyEvent.VK_R);
	cbMenuItem.addItemListener(this);
	group2.add(cbMenuItem);
	submenu.add(cbMenuItem);

	cbMenuItem = new JCheckBoxMenuItem("Bleu", false) ;
	cbMenuItem.setMnemonic(KeyEvent.VK_B);
	cbMenuItem.addItemListener(this);
	group2.add(cbMenuItem);
	submenu.add(cbMenuItem);

		// … vert, etc.

	menu = new JMenu("Aide");
	menu.setMnemonic(KeyEvent.VK_A); 
	menuBar.add(Box.createHorizontalGlue());
	menuBar.add(menu);
    
	} // fin du constructeur

	public void actionPerformed(ActionEvent e) {
		JMenuItem source 
				= (JMenuItem)(e.getSource());
		String s = "Detection d’ActionEvent."
				+ newline
				+ "    source de l’ev.: " 
				+ source.getText()
				+ " (instance de " 
				+ getClassName(source) + ")";
		output.append(s + newline);
	}

	public void itemStateChanged(ItemEvent e) {
		JMenuItem source 
				= (JMenuItem)(e.getSource());
		String s = "Detection d’ItemEvent."
				+ newline
				+ "    source de l’ev.: " 
				+ source.getText()
				+ " (instance de " 
				+ getClassName(source) + ")"
				+ newline
				+ "    Nouvel Etat: " 
				+ ((e.getStateChange()== 
						ItemEvent.SELECTED)?
						"selected":"unselected");
		output.append(s + newline);
	}

	protected String getClassName(Object o) {
		String classString = o.getClass().getName();
		int dotIndex = classString.lastIndexOf(".");
		return classString.substring(dotIndex+1);
	}
}