|
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.
|
|
|
|
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... |
|
|
 |
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 |
|
|
 |
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 |
|
|
 |
- 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 |
|
|
 |
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: |
|
|
|
|
|
|
|
|
|
|
|
|
 |
|
|
|
|