# mouseEntered()



## crackbag (19. Aug 2008)

Hab den folgenden Code, der ein kleines Rechteck in ein Fenster added. Das Rechteck kann man auf dem Fenster verschieben. 
Jetzt würde ich gerne eine kleine anzeige haben, wenn man mit der Maus über das Rechteck geht anzeigt, dass man in der Fläche ist, weiß aber nicht wie ich das umsetzen kann mit der mouseEntered Methode. 
Sitze vielleicht auch schon etwas zu lange an dem Teil.. 



```
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;

class MyCanvas extends Canvas implements MouseListener,MouseMotionListener {

	private int rectWidth=200;
	private int rectHeight = 70;
	private Rectangle rect = new Rectangle(0, 0, rectWidth, rectHeight);
	private Graphics2D g2;
	private int preX, preY;
	private boolean isFirstTime = true;
	private Rectangle area;
	private boolean pressOut = false;
	private int locationX;
	private int locationY;
	private Color borderColor; 
	private Color areaColor; 

	public MyCanvas() {
		
		this.locationX = 250;
		this.locationY = 250;
		
		setBackground(Color.white);
		addMouseMotionListener(this);
		addMouseListener(this);
	}

	public void mousePressed(MouseEvent e) {
		preX = rect.x - e.getX();
		preY = rect.y - e.getY();

		if (rect.contains(e.getX(), e.getY()))
			updateLocation(e);
		else {
			pressOut = true;
		}
	}

	public void mouseDragged(MouseEvent e) {
		if (!pressOut)
			updateLocation(e);
	}

	public void mouseReleased(MouseEvent e) {
		if (rect.contains(e.getX(), e.getY()))
			updateLocation(e);
		else {
			pressOut = false;
		}
	}

	public void mouseMoved(MouseEvent e) {
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
		//
	}

	public void updateLocation(MouseEvent e) {
		rect.setLocation(preX + e.getX(), preY + e.getY());

		repaint();
	}

	public void paint(Graphics g) {
		update(g);
	}

	public void update(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		Dimension dim = getSize();
		int w = (int) dim.getWidth();
		int h = (int) dim.getHeight();
		g2.setStroke(new BasicStroke(8.0f));

		if (isFirstTime) {
			area = new Rectangle(dim);
			rect.setLocation(this.locationX / 2 - 50, this.locationY / 2 - 25);
			isFirstTime = false;
		}

		// Clears the rectangle that was previously drawn.
		g2.setPaint(Color.white);
		g2.fillRect(0, 0, w, h);

		g2.setColor(this.borderColor);// Rand
		g2.draw(rect);
		g2.setColor(this.areaColor);// Fläche
		g2.fill(rect);

	}

	boolean checkRect() {
		if (area == null) {
			return false;
		}

		if (area.contains(rect.x, rect.y, 100, 50)) {
			return true;
		}
		int new_x = rect.x;
		int new_y = rect.y;

		if ((rect.x + 100) > area.getWidth()) {
			new_x = (int) area.getWidth() - 99;
		}
		if (rect.x < 0) {
			new_x = -1;
		}
		if ((rect.y + 50) > area.getHeight()) {
			new_y = (int) area.getHeight() - 49;
		}
		if (rect.y < 0) {
			new_y = -1;
		}
		rect.setLocation(new_x, new_y);
		return false;
	}
}
```


----------



## Quaxli (19. Aug 2008)

Bevor Du Dein eigentlich Problem angehst, solltest Du mal Deinen Code überarbeiten. Leider hast Du kein lauffähiges Beispiel gepostet. Da Du da aber einen import von JFrame stehen hast, Deine Klasse aber von Canvas erbt, gehe ich davon aus, daß Du AWT- und Swing-Elemente mischt. Das ist grundsätzlich nicht unbedingt gut und kann zu schwer nachvollziehbaren Fehler führen. Du solltest daher das Canvas durch ein JPanel ersetzten.

Auch die Kombination aus überschriebener Update-Methode und dem Aufruf dieser aus der paint-Methode ist nicht sehr schön, um es mal so zu sagen. Zum Zeichnen überschreibt man üblicherweise die paint-Methode, das wir auch in der API schon so empfohlen:



> Most applications that subclass Canvas should override this method in order to perform some useful operation
> (typically, custom painting of the canvas). The default operation is simply to clear the canvas.
> Applications that override this method need not call super.paint(g)



Zudem ruft update wieder paint auf, wie man aus der API entnehmen kann:



> This method is called in response to a call to repaint. The canvas is first cleared by filling it with the background
> color, and then completely redrawn by calling this canvas's paint method.
> Note: applications that override this method should either call super.update(g) or incorporate the functionality
> described above into their own code.



Du baust Dir hier also eine Schleife, die so sicher nicht gewollt ist.


----------



## Quaxli (19. Aug 2008)

Ich hab' Dein Programm mal etwas ausgedünnt, d. h. Variablen und Methoden rausgeworfen und auf Swing umgestellt.


```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MyPanel extends JPanel implements MouseListener, MouseMotionListener {

	private static final long	serialVersionUID	= 1L;
	
	private Rectangle		rect;
  private boolean hit = false;
  private Point old = null;

	public static void main(String[] args){
		new MyPanel();
	}
	
	public MyPanel() {

		//Rectangle hier erzeugen
	  rect = new Rectangle(0,0,50,50);
		
	  //Panel in JFrame einbetten
		JFrame frame = new JFrame("Move me");
		frame.setLocation(100, 100);
		frame.setSize(300, 300);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		setBackground(Color.white);
		addMouseListener(this);
		addMouseMotionListener(this);

    frame.add(this);
		frame.setVisible(true);
	}

	//Wenn Mausklick innerhalb Rechteck, boolean setzen und Punkt für die Bewegungsermittlung merken
	public void mousePressed(MouseEvent e) {
		if (rect.contains(e.getPoint())){
			hit = true;
			old = e.getPoint();
		}
	}

	//Wenn Maus bei angeklicktem Rechteck bewegt wird, Position aktualisieren
	public void mouseDragged(MouseEvent e) {
		if (hit){
			updateLocation(e.getPoint());
		}
	}

	//Beim Loslassen boolean und "Merkpunkt" zurück setzen und nochmal repaint, damit das Rechteck
	//wieder grün wird
	public void mouseReleased(MouseEvent e) {
			hit = false;
			old = null;
			repaint();
	}

	//Reswt wird nicht gebraucht
	public void mouseClicked(MouseEvent e) {}	
	
	public void mouseEntered(MouseEvent e) {}

	public void mouseExited(MouseEvent e) {}

	public void mouseMoved(MouseEvent e) {	}

	//Position updaten
	public void updateLocation(Point p) {
		//Deltas der Punkte alt vs. neu errechnen und auf x-/y-Position des Rechtecks addieren
		rect.x += p.x - old.x;
		rect.y += p.y - old.y;
		
		//Sicherstellen, daß das Rechteck innerhalbe des JPanel bleibt
		if(rect.x<0){
			rect.x = 0;
		}
		
		if(rect.x+rect.width>getWidth()){
			rect.x = getWidth()-rect.width;
		}
		
		if(rect.y<0){
			rect.y = 0;
		}
		
		if(rect.y+rect.height>getHeight()){
			rect.y = getHeight()-rect.height;
		}
		
		//dieser Punkt ist jetzt der neue alte Punkt ;)
		old = p;
		//neu zeichnen
		repaint();
	}

	//bei Swing überschreibt man paintComponent(..)
	public void paintComponent(Graphics g) {
		
		//super-Aufruf nicht vergessen
    super.paintComponent(g);
		
    //Wenn angeklickt, Rechteck rot zeichnen, sonst grün
    if(!hit){
		  g.setColor(Color.GREEN);
		}else{
			g.setColor(Color.RED);
		}
		
		g.drawRect(rect.x, rect.y, rect.width, rect.height);
		
	}





}
```


----------



## Marco13 (19. Aug 2008)

Um die eigentliche Frage zu beantworten: Man KÖNNTE einen MouseEntered-Event werfen, den man selbst gebaut hat - aber das würde keinen Sinn machen (der MouseEvent wäre ja "Mouse Entered" - mit dem Canvas als Source - obwohl die Maus nach wie vor auf dem Canvas ist und WAR. 

In der MouseMoved abfragen, ob der alte Punkt außerhalb und der neue innerhalb des Rechtecks ist, und dann die entsprechende Aktion auszuführen, wäre wohl sinnvoller....


----------



## crackbag (19. Aug 2008)

Vielen Dank, ihr habt mir sehr geholfen!


----------

