# Eigene JComponent mit MouseListener versehen



## 1337iceskater (11. Nov 2009)

Hallo Leute,

ich habe mal wieder ein Problem, diesmal in Swing, und habe noch keine Lösung im Forum gefunden.
Wäre Klasse, wenn ihr mir wieder so schnell helfen könntet.

Also hier das Problem:

Ich versuche selbstgestaltete Felder zu programmieren, die z.B. beim Anklicken ihre Farbe wechseln können. Da ich davon mehrere habe, dachte ich, dass ich die Kontrolle per MouseListener nicht in der Mutter-Komponente (also in dem JPanel wo alle drin sind) mache, sondern jedem Feld seinen eigenen MouseListener geben könnte.
Im MouseListener wird auch ne Testausgabe gemacht, die kommt aber leider nicht zum Vorschein.

Hier jetzt erstmal der Code:


```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JComponent;

public class Field extends JComponent implements MouseListener{

	private static final long serialVersionUID = 1L;
	private int x;
	private int y;
	private int lang;
	private Color color = Color.BLUE;
	
	public Field(int x, int y, int lang){
		this.setX(x);
		this.setY(y);
		this.setLang(lang);
		this.addMouseListener(this);
		this.setSize(lang, lang);
	}
	
	public int min(int i, int j){
		if(i < j){
			return i;
		}
		else{
			return j;
		}
	}
	
	public void setColor(Color col){
		this.color = col;
	}
	
	public void draw(Graphics g){
		g.setColor(color);
		g.fillRoundRect(x, y, lang, lang, lang/2, lang/2);
	}

	@Override
	public void mouseClicked(MouseEvent e){
		Point p = e.getPoint();
		System.out.println("rofl");
		if(p.getX()<this.x+this.lang&&p.getX()>this.x&&p.getY()<this.y+this.lang&&p.getY()>this.y){
			this.setColor(Color.BLACK);
		}
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent e){
		System.out.println("X");
	}

	@Override
	public void mouseExited(MouseEvent e){
		
	}

	@Override
	public void mousePressed(MouseEvent e){
		
	}

	@Override
	public void mouseReleased(MouseEvent e){
		
	}
}
```

Ich hoffe ihr könnt mir weiterhelfen.

Danke schonmal.

LG von mir^^


----------



## Java@home (11. Nov 2009)

Hi, 
bitte mal den ganzen Code!


----------



## Michael... (11. Nov 2009)

Kann keinen Fehler finden. Bist Du Dir sicher, dass Du die Komponente mit der Maus erwischt bzw. dass die Komponente die Größe und Lage hat die Du vermutest?


----------



## 1337iceskater (11. Nov 2009)

das ist schon der ganze code der Klasse, diese Elemente werden dann mit der folgenden Funktion in ein JPanel hinzugefügt. Dieses JPanel liegt dann in dem JFrame was als Hauptfenster dient. Ich poste am Ende mal alle Klassen, die ich zur Zeit verwende.

Funktion zum Hinzufügen:


```
private static Vector<Field> fields = new Vector<Field>();

public void initFields(){
	for(int i = 0; i < fieldRow; i ++){
		for(int j = 0; j < fieldCol; j++){
			fields.add(new Field(j*lang, i*lang, lang));
		}
	}
}
```

So, und hier dann die kompletten Klassen:

Field-Klasse:

```
package risiko;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JComponent;

public class Field extends JComponent implements MouseListener{

	private static final long serialVersionUID = 1L;
	private int x;
	private int y;
	private int lang;
	private Color color = Color.BLUE;
	
	public Field(int x, int y, int lang){
		this.setX(x);
		this.setY(y);
		this.setLang(lang);
		this.addMouseListener(this);
		this.setSize(lang, lang);
	}
	
	public int min(int i, int j){
		if(i < j){
			return i;
		}
		else{
			return j;
		}
	}
	
	public void setColor(Color col){
		this.color = col;
	}
	
	public void draw(Graphics g){
		g.setColor(color);
		g.fillRoundRect(x, y, lang, lang, lang/2, lang/2);
	}

	@Override
	public void mouseClicked(MouseEvent e){
		Point p = e.getPoint();
		System.out.println("rofl");
		if(p.getX()<this.x+this.lang&&p.getX()>this.x&&p.getY()<this.y+this.lang&&p.getY()>this.y){
			this.setColor(Color.BLACK);
		}
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent e){
		System.out.println("X");
	}

	@Override
	public void mouseExited(MouseEvent e){
		
	}

	@Override
	public void mousePressed(MouseEvent e){
		
	}

	@Override
	public void mouseReleased(MouseEvent e){
		
	}
	
	public boolean isIn(Point p){
		if(p.getX()<this.x+lang&&p.getX()>this.x){
			if(p.getY()<this.y+lang&&p.getY()>this.y){
				return true;
			}
		}
		return false;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getX() {
		return x;
	}

	public void setY(int y) {
		this.y = y;
	}

	public int getY() {
		return y;
	}

	public void setLang(int lang) {
		this.lang = lang;
	}

	public int getLang() {
		return lang;
	}
}
```

GameField-Klasse:


```
package risiko;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Vector;

import javax.swing.JPanel;

public class GameField extends JPanel implements MouseListener{

	
	private int lang;
	private int fieldCol = 10;
	private int fieldRow = 2;
	private static final long serialVersionUID = 1L;
	private static Vector<Field> fields = new Vector<Field>();

	public void initFields(){
		for(int i = 0; i < fieldRow; i ++){
			for(int j = 0; j < fieldCol; j++){
				fields.add(new Field(j*lang, i*lang, lang));
			}
		}
	}	
	
	public GameField(Dimension d){
		super();
		this.lang = (int)(d.getHeight()/7);
		this.setBackground(Color.WHITE);
//		this.addMouseListener(this);
		initFields();
	}
	
	@Override
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		for(int i = 0; i < fields.size(); i++){
			fields.get(i).draw(g);
		}
	}
	
	@Override
	public void mouseClicked(MouseEvent e){
		System.out.println("rofl");
		for(int i = 0; i < fields.size(); i++){
			if(fields.get(i).isIn(e.getPoint())){
				fields.get(i).setColor(Color.BLACK);
			}
			else{
				fields.get(i).setColor(Color.BLUE);
			}
		}
		repaint();
	}

	@Override
	public void mouseEntered(MouseEvent e){
		
	}

	@Override
	public void mouseExited(MouseEvent e){
		
	}

	@Override
	public void mousePressed(MouseEvent e){
		
	}

	@Override
	public void mouseReleased(MouseEvent e){
		
	}
}
```

Risiko-Klasse:


```
package risiko;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class Risiko extends JFrame{

	public static Dimension screen;
	private static GameField gf;
	private static final long serialVersionUID = 1L;
	
	public Risiko(){
		super("Risiko");
		screen = Toolkit.getDefaultToolkit().getScreenSize();
		this.setSize(screen);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLayout(new BorderLayout());
		
		this.addKeyListener(new KeyListener(){
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.getKeyCode()==KeyEvent.VK_ESCAPE){
					System.exit(0);
				}
			}
			@Override
			public void keyReleased(KeyEvent e) {
				
			}
			@Override
			public void keyTyped(KeyEvent e){
				
			}			
		});
		
		gf = new GameField(screen);
		
		JMenuBar mb = new JMenuBar();
		JMenu file = new JMenu("Datei");
		JMenuItem neu = new JMenuItem("Neues Spiel");
		
		JMenuItem ext = new JMenuItem("Beenden");
		
		file.add(neu);
		file.add(ext);
		mb.add(file);
		
		this.add(mb, BorderLayout.NORTH);
		this.add(gf, BorderLayout.CENTER);
		
		this.setVisible(true);
	}
	
	public static void main(String[] args){
		new Risiko();
	}
}
```

so, das ist jetzt erstmal ziemlich viel ;-)
hoffe das hilft weiter.
Danke


----------



## KrokoDiehl (11. Nov 2009)

So wie ich das sehe, fügst du deine Fields nirgends dem Panel hinzu, also in [c]initFields()[/c] ist kein [c]this.add( field );[/c]
Ich nehme an, dass daher keine MouseEvents ankommen.


----------



## Java@home (11. Nov 2009)

wo ist den der MouseListener(was machen die in all den anderen Klassen) in der Klasse Risiko?
Du willst doch, dass beim klicken auf die Componenten was passiert, oder?


----------



## 1337iceskater (11. Nov 2009)

Danke für den Hinweis, das hab ich wirklich nicht bedacht.

Leider hat das auch nichts an der Nichtfunktionalität geändert. Die initFields sieht jetzt so aus.


```
public void initFields(){
	for(int i = 0; i < fieldRow; i ++){
		for(int j = 0; j < fieldCol; j++){
			Field f = new Field(j*lang, i*lang, lang);
			fields.add(f);
			this.add(f);
		}
	}
}
```

Ich beginne langsam an mir zu zweifeln...


----------



## Java@home (11. Nov 2009)

Schaue dir das mal bitte etwas genauer an!

```
public GameField(Dimension d){
        super();
        this.lang = (int)(d.getHeight()/7);
        this.setBackground(Color.WHITE);
//      this.addMouseListener(this);
        initFields();
    }
```


----------



## 1337iceskater (11. Nov 2009)

Ich weiß, dass ich da den MouseListener nicht hinzufüge. Das liegt daran, dass das meine erste Variante ist. Da wollte ich alle Fields durchgehen, da die in dem Vector gespeichert sind, und wenn das Field dann den Punkt beinhaltet wird dort etwas mit dem Field gemacht. Das ist aber sehr unperformant.

Der MouseListener um den es geht befindet sich in der Klasse Field:


```
public Field(int x, int y, int lang){
	this.setX(x);
	this.setY(y);
	this.setLang(lang);
	this.addMouseListener(this);
	this.setBounds(0, 0, lang, lang);
}
```

Hier dann noch die Methoden des MouseListeners:


```
@Override
public void mouseClicked(MouseEvent e){
	Point p = e.getPoint();
	System.out.println("rofl");
	if(p.getX()<this.x+this.lang&&p.getX()>this.x&&p.getY()<this.y+this.lang&&p.getY()>this.y){
		this.setColor(Color.BLACK);
	}
	repaint();
}
@Override
public void mouseEntered(MouseEvent e){
	System.out.println("X");
}
@Override
public void mouseExited(MouseEvent e){
	
}
@Override
public void mousePressed(MouseEvent e){
	
}
@Override
public void mouseReleased(MouseEvent e){
	
}
```


----------



## Michael... (11. Nov 2009)

Färbe doch mal die Felder im Konstruktor ein, damit Du siehst ob und wo sie dargestellt werden.


----------



## 1337iceskater (11. Nov 2009)

Oh ich glaube ich hab den Fehler^^

ich hab meinem JPanel noch kein Null-Layout gegeben. Dadurch waren die Components jeweils nicht sichtbar gewesen.

Danke trotzdem für eure Hilfe =)


----------

