Enrera
Mòdul 6
Iniciació a la programació en Java
  Pràctica
1
2
3
4
   
Exercicis
Exercicis
 
 
  El ratolí (mouse)
   
 

El punter del ratolí que es passeja per un component és capaç de generar-hi esdeveniments de la classe java.awt.event.MouseEvent, els quals poden ser capturats i fets servir per a allò que convingui.

En aquesta pràctica generarem aquests esdeveniments sobre un objecte canvas, tot continuant-ne l'estudi iniciat a la pràctica anterior.

   
Atenció !
Com sempre, cal que hi hagi un listener per a aquests esdeveniments. Per a java.awt.MouseEvent en considerarem dos: java.awt.event.MouseListener, per a clicks i d'altres accions estàtiques, a més de l'entrada i la sortida del punter de l'àrea que ocupa el component, i java.awt.MouseMotionListener, per a capturar els esdeveniments associats al moviment del punter sobre el component.
   
Clics, entrades, sortides...
   
Pràctica Comencem per la interficie java.awt.event.MouseListener.
   
 
  • Creem el projecte Mouse01 com a "Basic Java Application" amb el següent codi:

    /*
    * @(#)Mouse01.java 1.0 02/10/27
    *
    * You can modify the template of this file in the
    * directory ..\JCreator\Templates\Template_1\Project_Name.java
    *
    * You can also create your own project template by making a new
    * folder in the directory ..\JCreator\Template\. Use the other
    * templates as examples.
    */
    //package myprojects.mouse01;
    import java.awt.*;
    import java.awt.event.*;
    class Mouse01 extends Frame implements ActionListener {

        ElMeuCanvas canvas;
        public Mouse01() { //constructor
            canvas=new ElMeuCanvas();
            add(canvas,BorderLayout.CENTER);
            Button boto=new Button("Esborrar");
            boto.addActionListener(this);
            add(boto,BorderLayout.SOUTH);
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    dispose();
                    System.exit(0);
                }
            });
        }
        public void actionPerformed (ActionEvent e) {
            canvas.repaint();
        }
        public static void main(String args[]) {
            System.out.println("Starting Mouse01...");
            Mouse01 mainFrame = new Mouse01();
            mainFrame.setSize(400, 400);
            mainFrame.setTitle("El ratolí");
            mainFrame.setVisible(true);
        }

    }
    class ElMeuCanvas extends Canvas implements MouseListener {

        public ElMeuCanvas () { //constructor
            super();
            addMouseListener(this);
        }

        public void mouseClicked(MouseEvent e) {
            int posX=e.getX();
            int posY=e.getY();
            Graphics g=getGraphics();
            g.setColor(Color.RED);
            g.fillOval(posX-3,posY-3,6,6);
            g.setColor(Color.BLUE);
            g.drawOval(posX-3,posY-3,6,6);
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

    }


    Hem posat un canvas (classe ElMeuCanvas, filla de java.awt.Canvas) a la posició BorderLayout.CENTER del frame. A la posició BorderLayout.SOUTH hi hem posat un botó que ha de servir per netejar el canvas. Per tant, el frame ha de ser listener del botó i, com a tal, ha d'implementar l'interfície java.awt.ActionListener i el seu únic mètode public void actionPerformed(ActionEvent e). La instrucció per netejar el canvas és el mètode public void repaint() que crida al corresponent mètode public void update (Graphics g) (vegeu la pràctica anterior)

  • El canvas ha de ser capaç de capturar els esdeveniments generats pel mouse. Per tant, n'ha de ser listener i, com a tal, ha d'implementar la interface java.awt.MouseListener i tots i cadascun dels seus mètodes, encara que alguns d'ells no es facin servir:

    • public void mouseClicked(MouseEvent e)per a capturar l'esdeveniment "fer click sobre un punt"

    • public void mousePressed(MouseEvent e)per a capturar l'esdeveniment "prèmer el botó (dret o esquerre) del ratolí"

    • public void mouseReleased(MouseEvent e)per a capturar l'esdeveniment "deixar anar el botó que prèviament estava apretat"


    • public void mouseEntered(MouseEvent e)per a capturar l'esdeveniment "el punter del ratolí entra a l'àrea ocupada pel component"


    • public void mouseExited(MouseEvent e)per a capturar l'esdeveniment "el punter del ratolí surt de l'àrea ocupada pel component"

  • Els mètodes public int getX() i public int getY() de la classe java.awt.event.MouseEvent ens proporcionen les coordenades del punt on es produeix l'esdeveniment. Aquí ho fem servir per capturar clicks i dibuixar petits cercles allà on s'han produït:


  • Podem ara jugar amb això: canviem els mètodes del canvas de la interface java.awt.event.MouseListener així:

    class ElMeuCanvas extends Canvas implements MouseListener {

        public ElMeuCanvas () { //constructor
            super();
            addMouseListener(this);
        }

        public void mouseClicked(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {

            int posX=e.getX();
            int posY=e.getY();
            Graphics g=getGraphics();
            g.setColor(Color.RED);
            g.fillOval(posX-3,posY-3,6,6);
            g.setColor(Color.BLUE);
            g.drawOval(posX-3,posY-3,6,6);

        }

        public void mouseReleased(MouseEvent e) {

            int posX=e.getX();
            int posY=e.getY();
            Graphics g=getGraphics();
            g.setColor(Color.CYAN);
            g.fillOval(posX-3,posY-3,6,6);
            g.setColor(Color.RED);
            g.drawOval(posX-3,posY-3,6,6);

        }

        public void mouseEntered(MouseEvent e) {

            repaint();

        }

        public void mouseExited(MouseEvent e) {
        }

    }


    Ara hem deixat de fer servir el mètode public void mouseClicked(MouseEvent e) i hem posat en ús public void mousePressed(MouseEvent e), public void mouseReleased(MouseEvent e) i public void mouseEntered(MouseEvent e). Amb el punter del mouse sobre el canvas, en prémer el botó apareixerà un petit cercle vermell voltat de blau, mentre que en deixar-lo anar apareixerà un altre petit cercle blau clar voltat de vermell. Naturalment es pot prémer en un punt i deixar anar en un altre punt...

    D'altra banda, cada vegada que el
    punter del mouse entri al canvas, aquest s'esborrarà.
   
Els Adapters
   
Atenció ! El paquet java.awt.event proporciona algunes eines que simplifiquen una mica això (però només una mica). Es tracta dels adapters: són classes que contenen només els mètodes de les corresponents interfícies i aquests mètodes són buits.
  • ComponentAdapter, per a la interfície java.awt.event.ComponentListener.

  • ContainerAdapter, per a la interfície java.awt.event.ContainerListener.

  • FocusAdapter, per a la interfície java.awt.event.FocusListener.

  • HierarchyBoundsAdapter, per a la interfície java.awt.event.HierarchyBoundsListener.

  • KeyAdapter, per a la interfície java.awt.event.KeyListener.

  • MouseAdapter, per a la interfície java.awt.event.MouseListener.

  • MouseMotionAdapter, per a la interfície java.awt.event.MouseMotionListener.

  • WindowAdapter, per a la interfície java.awt.event.WindowListener
  Així, per exemple, aquest és el codi font de java.awt.MouseListener, tal com l'ha programat Sun:
   
  /*
* @(#)MouseAdapter.java 1.15 01/12/03
*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/

package java.awt.event;

/**
* An abstract adapter class for receiving mouse events.
* The methods in this class are empty. This class exists as
* convenience for creating listener objects.
* <P>
* Mouse events let you track when a mouse is pressed, released, clicked,
* when it enters a component, and when it exits.
* (To track mouse moves and mouse drags, use the MouseMotionAdapter.)
* <P>
* Extend this class to create a <code>MouseEvent</code> listener
* and override the methods for the events of interest. (If you implement
* the<code>MouseListener</code> interface, you have to define all of
* the methods in it. This abstract class defines null methods for them
* all, so you can only have to define methods for events you care
* about.)
* <P>
* Create a listener object using the extended class and then register it
* with a component using the component's <code>addMouseListener</code>
* method. When a mouse button is pressed, released, or clicked (pressed
* and released), or when the mouse cursor enters or exits the component,
* the relevant method in the listener object is invoked
* and the <code>MouseEvent</code> is passed to it.
*
* @author Carl Quinn
* @version 1.8 08/02/97
*
* @see MouseEvent
* @see MouseListener
* @see <a href="http://java.sun.com/docs/books/tutorial/
* post1.0/ui/mouselistener.html">
* Tutorial: Writing a Mouse Listener</a>
* @see <a href="http://www.awl.com/cp/javaseries/jcl1_2.html">Reference: * The Java Class Libraries (update file)</a>
*
* @since 1.1
*/

public abstract class MouseAdapter implements MouseListener {

    /**
    * Invoked when the mouse has been clicked on a component.
    */

    public void mouseClicked(MouseEvent e) {}

    /**
    * Invoked when a mouse button has been pressed on a component.
    */

    public void mousePressed(MouseEvent e) {}

    /**
    * Invoked when a mouse button has been released on a component.
    */

    public void mouseReleased(MouseEvent e) {}

    /**
    * Invoked when the mouse enters a component.
    */

    public void mouseEntered(MouseEvent e) {}

    /**
    * Invoked when the mouse exits a component.
    */
    public void mouseExited(MouseEvent e) {}
}

   
  El fet que en un adapter, ja hi siguin tots els mètodes fa que només haguem de preocupar-nos de sobreescriure aquells que ens interessin i deixar de banda els altres. El listener ja no és l'objecte (i ja no cal implementar-li ni la interfície ni els mètodes) sinó l'adapter que se li associa. El següent codi per a la classe ElMeuCanvas és completament equivalent al que hem donat al principi de la pràctica:
   
 

class ElMeuCanvas extends Canvas {

      public ElMeuCanvas () { //constructor
        super();
          addMouseListener(new MMouseAdapter(this));
      }

}
 

class MMouseAdapter extends MouseAdapter {

    ElMeuCanvas canvas;

    public MMouseAdapter (ElMeuCanvas c) {
//constructor
        super();
        canvas=c;
    }

    public void mouseClicked(MouseEvent e) {
        int posX=e.getX();
        int posY=e.getY();
        Graphics g=getGraphics();
        g.setColor(Color.RED);
        g.fillOval(posX-3,posY-3,6,6);
        g.setColor(Color.BLUE);
        g.drawOval(posX-3,posY-3,6,6);
    }

    public void mousePressed(MouseEvent e) {
    }

}

   
Oi que ara podeu entendre una mica més bé això que fa JCreator?
   
          addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                dispose();
                System.exit(0);
            }
        });
   
  Però, per entendre-ho del tot, caldria discutir una mica sobre classes i mètodes abstractes... Això arribarà aviat, eh?
   
Els moviments del mouse
   
Pràctica
  • L'interfície java.awt.event.MouseMotionListener té dos mètodes:

    • public void mouseDragged(MouseEvent e), per a capturar l'arrossegament del punter del ratolí amb el botó apretat.

    • public void mouseMoved(MouseEvent e), per a capturar el moviment del punter del ratolí amb el botó lliure.

  • Creem el projecte Mouse02 com a "Basic Java Application" amb el codi següent::

    /*
    * @(#)Mouse02.java 1.0 02/10/27
    *
    * You can modify the template of this file in the
    * directory ..\JCreator\Templates\Template_1\Project_Name.java
    *
    * You can also create your own project template by making a new
    * folder in the directory ..\JCreator\Template\. Use the other
    * templates as examples.
    *
    */
    //package myprojects.mouse02;

    import java.awt.*;
    import java.awt.event.*;

    class Mouse02 extends Frame implements ActionListener {

        ElMeuCanvas canvas;

        public Mouse02() { //constructor
            canvas=new ElMeuCanvas();
            add(canvas,BorderLayout.CENTER);
            Button boto=new Button("Esborrar");
            boto.addActionListener(this);
            add(boto,BorderLayout.SOUTH);
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    dispose();
                    System.exit(0);
                }
            });
        }
        public void actionPerformed (ActionEvent e) {
            canvas.repaint();
        }
        public static void main(String args[]) {
            System.out.println("Starting Mouse02...");
            Mouse02 mainFrame = new Mouse02();
            mainFrame.setSize(400, 400);
            mainFrame.setTitle("El ratolí");
            mainFrame.setVisible(true);
        }

    }

    class ElMeuCanvas extends Canvas implements MouseListener,
                                                MouseMotionListener {

        public ElMeuCanvas () { //constructor
            super();
            addMouseListener(this);
            addMouseMotionListener(this);
        }

        public void mouseDragged(MouseEvent e) {
            int posX=e.getX();
            int posY=e.getY();
            Graphics g=getGraphics();
            g.setColor(Color.RED);
            g.fillOval(posX-3,posY-3,6,6);
        }

        public void mouseMoved(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
        }

        public void mousePressed(MouseEvent e) {
        }

        public void mouseReleased(MouseEvent e) {
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

    }


    en el qual implementem, a més de java.awt.event.MouseListener, l'interface java.awt.event.MouseMotionListener amb els seus dos mètodes: public void mouseDragged(MouseEvent e) que fem servir per dibuixar petits cercles, i public void mouseMoved(MouseEvent e), que no fem servir.

  • Quan arrosseguem el punter sobre el canvas el resultat és aquest:


  • Ara podeu experimentar amb l'altre mètode: public void mouseMoved(MouseEvent e) i omplir-lo amb algun codi...
   
Dibuixem amb traç continu
   
Atenció ! Ja haureu experimentat que, si arrosseguem el botó massa ràpid, el traç es trenca. Com dibuixar amb traç continu?
   
  La següent modificació de la classe ElMeuCanvas ho aconsegueix: estudieu-ne ben bé el codi!
   
  class ElMeuCanvas extends Canvas implements MouseListener,
                                            MouseMotionListener {
    int iniX,iniY;
      public ElMeuCanvas () { //constructor
        super();
        addMouseListener(this);
          addMouseMotionListener(this);
      }
      public void mouseDragged(MouseEvent e) {
        int posX=e.getX();
        int posY=e.getY();
        Graphics g=getGraphics();
        g.setColor(Color.RED);
        g.drawLine(iniX,iniY,posX,posY);
        iniX=posX;
        iniY=posY;
    }

    public void mouseMoved(MouseEvent e) {
        int posX=e.getX();
        int posY=e.getY();
        Graphics g=getGraphics();
        g.setColor(Color.GREEN);
        g.drawLine(iniX,iniY,posX,posY);
        iniX=posX;
        iniY=posY;
    }

      public void mousePressed(MouseEvent e) {
          iniX=e.getX();
        iniY=e.getY();
      }

    public void mouseReleased(MouseEvent e) {

          iniX=e.getX();
        iniY=e.getY();
      }

    public void mouseEntered(MouseEvent e) {

          iniX=e.getX();
        iniY=e.getY();
      }

    public void mouseExited(MouseEvent e) {
    }

}

   
  Observeu com, a l'arrossegar, el traç és vermell, mentre que al moure, el traç és verd:
   
 
   
   
   
 
Amunt