C. Recanati InHM Master M1, 2012 Eléments de correction des TP 9 et 10 // Constants.java import java.awt.*; public interface Constants { // Les types d'elements int LIGNE = 101; int RECTANGLE = 102; int CERCLE = 103; int COURBE = 104; // Les conditions initiales int DEFAULT_ELEMENT_TYPE = RECTANGLE; Color DEFAULT_ELEMENT_COLOR = Color.green; } // SketcherFrame.java version 1 import java.awt.*; import java.awt.event.*; import javax.swing.* ; public class SketcherFrame extends JFrame implements Constants { // membres protected JTextArea output; protected JScrollPane scrollPane ; private JMenuBar menuBar; // couleur et type de l'element courant private Color elementColor = DEFAULT_ELEMENT_COLOR; private int elementType = DEFAULT_ELEMENT_TYPE; protected String newline = "\n"; // constructeurs public SketcherFrame(String titre) { // pour definir les menus JMenu menu, submenu; JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; setTitle(titre); setDefaultCloseOperation(EXIT_ON_CLOSE); // Créer l’éditeur de texte scrollé output = new JTextArea(10, 80); output.setEditable(false); scrollPane = new JScrollPane(output); //l’ajouter au cadre Container contentPane = getContentPane(); contentPane.add(scrollPane, BorderLayout.CENTER) ; //Créer la barre de menu menuBar = new JMenuBar(); setJMenuBar(menuBar); //Construire le premier menu. menu = new JMenu("Fichiers"); menu.setMnemonic(KeyEvent.VK_F); menuBar.add(menu); //un groupe de JMenuItems pour ce menu menuItem = new JMenuItem("Ouvrir", KeyEvent.VK_O); menuItem.setAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_1, ActionEvent.ALT_MASK)); menu.add(menuItem); menuItem = new JMenuItem("texte et icone", new ImageIcon("icone.gif")); menuItem.setMnemonic(KeyEvent.VK_A); menu.add(menuItem); menuItem = … etc … menu.addSeparator(); … etc … // Construire le second menu menu = new JMenu("Elements"); … ibid que précédemment avec le menu Fichiers menuBar.add(menu); //un groupe d’items type radio button ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem ("Ligne", elementType ==LIGNE); rbMenuItem.setMnemonic(KeyEvent.VK_L); group.add(rbMenuItem); rbMenuItem.addActionListener (new TypeListener(LIGNE)); menu.add(rbMenuItem); // rebelotte avec le type suivant rbMenuItem = new JRadioButtonMenuItem ("Rectangle", elementType == RECTANGLE); … rbMenuItem.addActionListener (new TypeListener(RECTANGLE)); … menu.addSeparator(); // le sous menu pour les couleurs submenu = new JMenu("Couleur"); submenu.setMnemonic(KeyEvent.VK_C); // un groupe de check box menu items ButtonGroup group2 = new ButtonGroup(); cbMenuItem = new JCheckBoxMenuItem("Rouge", elementColor.equals(Color.red)); cbMenuItem.setMnemonic(KeyEvent.VK_R); group2.add(cbMenuItem); cbMenuItem.addActionListener (new ColorListener(Color.red)); submenu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Bleu", elementColor.equals(Color.blue)); // … etc … //Construire le dernier menu. menu = new JMenu("Aide"); menu.setMnemonic(KeyEvent.VK_A); // ajouter un separateur horizontal avant menuBar.add(Box.createHorizontalGlue()); menuBar.add(menu); } class TypeListener implements ActionListener { private int type; // un type d’element TypeListener(int type) { this.type = type; } public void actionPerformed(ActionEvent e) { elementType = type; JMenuItem source = (JMenuItem)(e.getSource()); String s = "ActionEvent detecte" +" dans TypeListener" + newline + " Event source: " + source.getText() + " (une instance de " + getClassName(source) + ")"; output.append(s + newline); } } class ColorListener implements ActionListener { private Color color; // couleur d’element ColorListener(Color color) { // memoriser la couleur … } public void actionPerformed(ActionEvent e) { elementColor = color; JMenuItem source = (JMenuItem)(e.getSource()); String s = "ActionEvent detecte" + " dans ColorListener." + newline … etc … + getClassName (…) + … } } protected String getClassName(Object o) { String classString = o.getClass().getName(); int dotIndex = classString.lastIndexOf("."); return classString.substring(dotIndex+1); } } // // Sketcher.java import java.awt.*; import java.awt.event.*; import java.util.*; public class Sketcher { // private SketcherModel model; private SketcherView view; private static SketcherFrame window; private static Sketcher theApp; /* */ public static void main(String[] args) { theApp = new Sketcher(); theApp.init(); } public SketcherFrame getWindow() { return window; } public SketcherModel getModel() { return model; } public SketcherView getView() { return view; } public void init() { window = new SketcherFrame("Dessin", this); Toolkit leKit = window.getToolkit(); Dimension wndSize = leKit.getScreenSize(); window.setBounds(wndSize.width/4, wndSize.height/4, wndSize.width/2, wndSize.height/2); // model = new SketcherModel(); view = new SketcherView(this); model.addObserver((Observer)view); window.getContentPane().add(view, BorderLayout.CENTER); window.setVisible(true); // } } // // SketcherView.java // class SketcherView extends JPanel implements Observer, Constants { private Sketcher theApp; // Objet Application public SketcherView(Sketcher theApp) { this.theApp = theApp; // permettra d’accéder au modèle // mettre un fond blanc au panneau // créer un MouseHandler (défini plus loin) et l’enregistrer } public void update(Observable o, Object rectangle) { // code correspondant aux modifs du modèle // rectangle est ici l’objet passé à notifyObservers if (rectangle == null) repaint(); else repaint( (Rectangle) rectangle); } public void paintComponent(Graphics g) { super.paintComponent(g); // récupérer l’iterateur de la LinkedList des éléments Iterator elements = … while (elements.hasNext()) { Element element = (Element) elements.next(); // dessiner l’élément dans sa couleur // (utiliser draw de Graphics2D) } } class MouseHandler extends MouseInputAdapter { private Point debut; // position de la souris au clic private Point dernier; // position de la souris en drag private Element tempElement ; // l'element temporaire private Graphics2D g2D; // le contexte graphique public void mousePressed (MouseEvent e) { // récupérer le point de debut // initialiser g2D en mode XOR pour basculer // entre la couleur courante et le blanc } public void mouseDragged (MouseEvent e) { // récupérer le dernier point if (tempElement == null) { // créer un élément temporaire } else { // effacer le precedent // modifier l'element temporaire } // dessiner l’élément temporaire } public void mouseReleased (MouseEvent e) { if (tempElement != null) // ajouter l’élément temporaire au modèle if (g2D != null) { g2D.dispose(); } // remettre tous les membres du MouseHandler à null } } } Pour terminer l’architecture Modèle/Vue : // // // SketcherModel.java import java.util.*; class SketcherModel extends Observable { protected LinkedList ListeElements = new LinkedList(); public boolean remove(Element element) { boolean removed = ListeElements.remove(element); if (removed) { // notifier les vues } return removed; } public void add(Element element) { ListeElements.add(element); setChanged(); notifyObservers(element.getBounds()); } public Iterator getIterator() { // retourner l’iterateur sur la liste } } // // // nouveau SketcherView.java import import import import import import javax.swing.*; javax.swing.event.*; java.util.*; java.awt.*; java.awt.geom.*; java.awt.event.*; // pour Observer class SketcherView extends JPanel implements Observer, Constants { private Sketcher theApp; // Objet Application public SketcherView(Sketcher theApp) { this.theApp = theApp; setBackground(Color.white); setOpaque(true); MouseHandler handler = new MouseHandler(); addMouseListener(handler); addMouseMotionListener(handler); } public void update(Observable o, Object rectangle) { // code correspondant aux modifs du modèle if (rectangle == null) repaint(); else repaint( (Rectangle) rectangle); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2D = (Graphics2D) g; Iterator elems = theApp.getModel().getIterator(); Element element; while (elems.hasNext()) { element = (Element) elems.next(); g2D.setPaint(element.getColor()); g2D.draw(element.getShape()); } } class MouseHandler extends MouseInputAdapter { private Point debut; // position au clic private Point dernier;// position en drag private Element tempElement ; // temporaire private Graphics2D g2D; public void mousePressed (MouseEvent e) { System.out.println("clic"); debut = e.getPoint(); g2D = (Graphics2D) getGraphics(); g2D.setPaint (theApp.getWindow().getElementColor()); g2D.setXORMode(Color.white); } public void mouseDragged (MouseEvent e) { System.out.println("drag"); dernier = e.getPoint(); if (tempElement == null) tempElement = createElement (debut, dernier) ; else { // effacer tempElement // (le precedent) // le modifier (-> nouveau) } // dessiner tempElement (le nouveau) } public void mouseReleased (MouseEvent e) { System.out.println("relacher"); if (tempElement != null) { // theApp.getModel().add(tempElement); tempElement = null; } if (g2D != null) { g2D.dispose(); g2D = null; } debut = dernier = null; } private Element createElement (Point debut, Point fin) { switch(theApp.getWindow().getElementType()) { case LIGNE: return new … case RECTANGLE: return new Element.Rectangle(debut, fin,… case CERCLE: … } return null; } } } // SketcherFrame.java // version 2 import java.awt.*; import java.awt.event.*; import javax.swing.* ; public class SketcherFrame extends JFrame implements Constants { private Sketcher theApp; // l'objet Application private JMenuBar menuBar; // la barre de menu // le type et la couleur d’element par defaut private Color elementColor = DEFAULT_ELEMENT_COLOR; private int elementType = DEFAULT_ELEMENT_TYPE; public SketcherFrame (String titre, Sketcher theApp) { JMenu menu, submenu; // pour les menus JMenuItem menuItem; JRadioButtonMenuItem rbMenuItem; JCheckBoxMenuItem cbMenuItem; setTitle(titre); this.theApp = theApp; setDefaultCloseOperation(EXIT_ON_CLOSE); //Créer la barre de menu menuBar = new JMenuBar(); setJMenuBar(menuBar); //Construire le premier menu. menu = new JMenu("Fichiers"); menu.setMnemonic(KeyEvent.VK_F); menuBar.add(menu) ; // Construire le second menu menu = new JMenu("Elements"); menu.setMnemonic(KeyEvent.VK_E); menuBar.add(menu); //un groupe de radio button menu items ButtonGroup group = new ButtonGroup(); rbMenuItem = new JRadioButtonMenuItem("Ligne", elementType == LIGNE); rbMenuItem.setMnemonic(KeyEvent.VK_L); group.add(rbMenuItem); rbMenuItem.addActionListener (new TypeListener(LIGNE)); menu.add(rbMenuItem); rbMenuItem = new JRadioButtonMenuItem("Rectangle", elementType == RECTANGLE); rbMenuItem.setMnemonic(KeyEvent.VK_R); group.add(rbMenuItem); rbMenuItem.addActionListener (new TypeListener(RECTANGLE)); menu.add(rbMenuItem); // rbMenuItem = … etc // un separateur menu.addSeparator(); // un sous menu submenu = new JMenu("Couleur"); submenu.setMnemonic(KeyEvent.VK_C); // un groupe de check box menu items ButtonGroup group2 = new ButtonGroup(); cbMenuItem = new JCheckBoxMenuItem("Rouge", elementColor.equals(Color.red)); cbMenuItem.setMnemonic(KeyEvent.VK_R); group2.add(cbMenuItem); cbMenuItem.addActionListener (new ColorListener(Color.red)); submenu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Bleu", elementColor.equals(Color.blue)); cbMenuItem.setMnemonic(KeyEvent.VK_B); group2.add(cbMenuItem); cbMenuItem.addActionListener (new ColorListener(Color.blue)); submenu.add(cbMenuItem); cbMenuItem = new JCheckBoxMenuItem("Vert", …) ; … menu.add(submenu); // fin du second menu //Construire le dernier menu Aide a droite menu = new JMenu("Aide"); menu.setMnemonic(KeyEvent.VK_A); menuBar.add(Box.createHorizontalGlue()); menuBar.add(menu); } // les classes internes ecouteurs // d’items des menus class TypeListener implements ActionListener { private int type; TypeListener(int type) { this.type = type; } public void actionPerformed(ActionEvent e) { elementType = type; } } class ColorListener implements ActionListener { private Color color; ColorListener(Color color) { this.color = color; } public void actionPerformed(ActionEvent e) { elementColor = color; } } // les accesseurs de elementColor et elementType public Color getElementColor() { return elementColor; } public int getElementType() { return elementType; } }