Java -- Wie realisiert man anklickbare Bilder?

  • Ersteller Mitglied 7974
  • Erstellt am

Mitglied 7974

Gast
Hallo!

Ich möchte mit Java unter Swing ein Kartenspiel programmieren, stecke allerdings bei einer vielleicht simplen Sache fest. Man kennt ja von solchen Spielen, dass man auf eine Karte klickt und diese dann in die Mitte des Bildschirms schwebt und auf dem Ablagestapel landet.

Zu diesem Zweck ist es natürlich nötig, abzufragen, ob die Karte überhaupt angeklickt wurde. Weil bei mir jede Karte als eigenes JPanel-Objekt realisiert wurde, wäre es mir natürlich am liebsten, wenn ich der Karten-Klasse einfach einen MouseListener hinzufügen könnte. Das lässt sich auch machen, aber dann bezieht sich der Listener auf den kompletten JPanel welcher den kompletten JFrame einnimmt (public void mouseEntered(MouseEvent event) { ... } führt die Befehle in den geschweiften Klammer schon dann aus, wenn sich der Mauszeiger nur über dem Panel befindet, nicht erst, wenn er sich über dem Bild aufhält).

Die Karte wird durch ein GIF-Image dargestellt. Meine nächste Idee wäre also gewesen, einfach das Bild für den MouseListener zu registrieren, aber das scheint nicht zu klappen (Fehler beim Kompilieren - MouseListener lässt sich angeblich nicht bei einem Bild einsetzen).

Ich finde es einfach äußerst unelegant, wenn ich bei einer objektorientierten Programmiersprache nicht das Objekt an sich anklicken kann, sondern überprüfen muss, wo auf dem Bildschirm die Maus geklickt hat, um dann zu entscheiden, ob sich der Punkt im Pixelbereich des Kartenbildes aufgehalten hat oder nicht.

Daher folgende Fragen:
  • Ist es möglich, einem Bild einen MouseListener zuzuordnen? Wenn ja, wie?
  • Kann man die Größe eines JPanels ändern? Wäre es möglich, den JPanel einfach an die Kartenbildgröße anzugleichen, sodass der MouseListener des JPanels scheinbar zum MouseListener des Kartenbilds wird? Wenn ja, wie?
  • Wie wäre es sonst noch möglich, herauszufinden, ob auf eine Karte geklickt wurde?

Vielen Dank für konstruktive Lösungsideen!
 

MatzeLoCal

Rheinischer Bohnapfel
Registriert
05.01.04
Beiträge
2.422
Mal mit mouseDown oder so ähnlich probiert? Das sollte nur auf klick reagieren.

Auf die ganz schnelle gefunden:
1.
2.
 

philo

Roter Stettiner
Registriert
13.10.04
Beiträge
973
Hallo!

Ich möchte mit Java unter Swing ein Kartenspiel programmieren, stecke allerdings bei einer vielleicht simplen Sache fest. Man kennt ja von solchen Spielen, dass man auf eine Karte klickt und diese dann in die Mitte des Bildschirms schwebt und auf dem Ablagestapel landet.

Zu diesem Zweck ist es natürlich nötig, abzufragen, ob die Karte überhaupt angeklickt wurde. Weil bei mir jede Karte als eigenes JPanel-Objekt realisiert wurde, wäre es mir natürlich am liebsten, wenn ich der Karten-Klasse einfach einen MouseListener hinzufügen könnte. Das lässt sich auch machen, aber dann bezieht sich der Listener auf den kompletten JPanel welcher den kompletten JFrame einnimmt (public void mouseEntered(MouseEvent event) { ... } führt die Befehle in den geschweiften Klammer schon dann aus, wenn sich der Mauszeiger nur über dem Panel befindet, nicht erst, wenn er sich über dem Bild aufhält).

Die Karte wird durch ein GIF-Image dargestellt. Meine nächste Idee wäre also gewesen, einfach das Bild für den MouseListener zu registrieren, aber das scheint nicht zu klappen (Fehler beim Kompilieren - MouseListener lässt sich angeblich nicht bei einem Bild einsetzen).

Ich finde es einfach äußerst unelegant, wenn ich bei einer objektorientierten Programmiersprache nicht das Objekt an sich anklicken kann, sondern überprüfen muss, wo auf dem Bildschirm die Maus geklickt hat, um dann zu entscheiden, ob sich der Punkt im Pixelbereich des Kartenbildes aufgehalten hat oder nicht.

Daher folgende Fragen:
  • Ist es möglich, einem Bild einen MouseListener zuzuordnen? Wenn ja, wie?
  • Kann man die Größe eines JPanels ändern? Wäre es möglich, den JPanel einfach an die Kartenbildgröße anzugleichen, sodass der MouseListener des JPanels scheinbar zum MouseListener des Kartenbilds wird? Wenn ja, wie?
  • Wie wäre es sonst noch möglich, herauszufinden, ob auf eine Karte geklickt wurde?

Vielen Dank für konstruktive Lösungsideen!

ohne deinen text gelesen zu haben. mal schnell ne antwort:

die bilder sind ja eigentlich labels und denen kannst du wie du schon sagtes listener zuordnen und zwar ungefähr so:

JLabel imageLabel = ....

imageLabel.addMouseListener(einMouseListener);

oder

imageLabel.addMouseListener(this);

dann muss this (also die aktuelle Klasse das MouseListener-Interface implementieren)

kannst die Bilder auch in Panels packen. Wenn die da einmal drin sind, nehmen sie die grösse der Bilder an, glaube ich.

naja, sehr kurze ansage, aber vielleicht hilft es ja.

gruss
philo
 

chrisdo

Gast
class MyClassWithImage extends MouseAdapter {
// Dein Code Dein Code Dein Code
// Hier musst du den MouseListener dem Bild hinzufügen Bild.addMouseListener(this);

public void mouseClicked(MouseEvent e) {
// Deine Action wenn das Bild angeklickt wurde
}

Wenn du keine andere Klasse extendest, dann würde ich den MouseAdapter nehmen, denn da musst du nicht jede Funktion implementieren (vorallem unnötig wenn sie sowieso leer bleiben werden).
 

Mitglied 7974

Gast
Danke für die Tipps. Ich probiere jetzt erstmal die JLabels aus, denn die anderen Links scheinen in etwa dieselben Vorgehen zu schildern, die ich schon ausprobiert hatte. Jedenfalls schon mal danke für die rege Anteilnahme. Ich hätte echt nicht damit gerechnet, gleich so viele Tipps zu bekommen. Danke!
 

Mitglied 7974

Gast
Jetzt habe ich endlich herausgefunden, wie man das Thema für meine Zwecke am besten realisieren kann. Eigentlich ist es ganz einfach. Zuerst muss man einen JPanel erzeugen, der als Container für die Karten dient. Dabei muss man allerdings beachten, dass ihm kein LayoutManager zugeordnet wird, also
Code:
JPanel panel = new JPanel(null)
. Dieser JPanel muss dann natürlich zu einem JFrame geaddet werden. Schließlich kann man nun weitere JPanels erzeugen (in meinem Fall also Karten), deren Größe und Position man frei mit
Code:
setBounds(int posX, int posY, int width, int height)
wählen kann. Und das beste von allem: Wenn der JPanel dieselbe Größe wie die Karte hat, ist es auch kein Problem mehr, wenn man dem JPanel direkt einen MouseListener zuordnet, denn weil Karte und JPanel gleich groß sind, reagiert Java prinzipiell tatsächlich auf das Bild. Hier mal eine JPanel-Klasse für Interessierte. Die dazu gehörige JFrame-Klasse müsst ihr euch noch selbst schreiben.

Code:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.imageio.*;

public class Pic extends JPanel {

	public Pic() {
	
		this.createImage();
		pX = 100;
		pY = 100;

		setBounds(pX,pY,100,100);
		addMouseListener(new MouseHandler());

	}
	
	public void paintComponent(Graphics g) {
		
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.drawImage(this.image, 0, 0, 100, 100, null);
		
	}
	
	private void createImage() {
		
		try {
			
			URL url    = Pic.class.getResource("herz-9.gif");
			this.image = ImageIO.read(url);
			
		}
		catch (IOException e) {
			
			e.printStackTrace();
			
		}
		
	}
	
	
	private Image image;
	private int pX;
	private int pY;
	
	
	private class MouseHandler extends MouseAdapter {
		
		public void mouseClicked(MouseEvent event) {
			
			System.out.println("Du hast auf die Karte geklickt!");
			
		}
		
	}
	
}

Der Code ist natürlich noch nicht praxisnah geschrieben, aber ich hoffe, das Konzept wird klar.

Also, nochmal danke für die vielen Tipps und 'nen schönen Abend noch!