# Hashmap mit 2D Graphics



## keram (5. Okt 2015)

Moin Leute,
ich bin momentan dabei einen kleines Spiel in Java zu programmieren.
Teil meines Spiels ist es ein fillRect mit Drag und Drop verschieben zu können.

Da ich noch recht neu in diesen Themenbereich bin bräuchte ich eure Hilfe.

Ich habe eine Reihe an fillRects erstellt und wollte diese nun in ein HashMap speichern um diese einzeln ansteuern zu können. Jedoch habe ich meine Schwierigkeiten diese in eine HashMap zu speichern. Da ich mir ohnehin unsicher bin ob ich die Funktionalität mit dieser Methode erreichen kann wollte ich euch einmal um Rat fragen.

Ich wollte das ganze über einen Mauslistener gestalten welcher beim klick überprüft welches Rechteck angeklickt wurde und möchte danach die Position des Rechtecke mit der Mausposition synchronisieren, habt ihr ein paar Denkansätze für mich wie ich die Funktionalität erreichen kann?


----------



## Joose (5. Okt 2015)

keram hat gesagt.:


> Teil meines Spiels ist es ein fillRect mit Drag und Drop verschieben zu können.



Was ist ein "fillRect"? Diese Klasse sagt mir leider gar nichts 



keram hat gesagt.:


> Ich habe eine Reihe an fillRects erstellt und wollte diese nun in ein HashMap speichern um diese einzeln ansteuern zu können. Jedoch habe ich meine Schwierigkeiten diese in eine HashMap zu speichern.



Was für Schwierigkeiten? Compilefehler oder Laufzeitfehler?



keram hat gesagt.:


> Da ich mir ohnehin unsicher bin ob ich die Funktionalität mit dieser Methode erreichen kann wollte ich euch einmal um Rat fragen.



Welche Funktionalität willst du denn erreichen? Eine HashMap ist nur ein Objekt um Values per eindeutigen Key anzusprechen. Daher bin ich mir nicht sicher was für eine Funktionalität du dir von einer HashMap erwartest.



keram hat gesagt.:


> Ich wollte das ganze über einen Mauslistener gestalten welcher beim klick überprüft welches Rechteck angeklickt wurde und möchte danach die Position des Rechtecke mit der Mausposition synchronisieren, habt ihr ein paar Denkansätze für mich wie ich die Funktionalität erreichen kann?



Was willst du da Synchronisieren? Meinst du wenn du dann die Maus bewegst das sich das Rechteck ebenfalls bewegt?
Mit einem MouseListener festlegen welches Rechteck ausgewählt wurde, und dann das "mouseMove" Event ebenfalls weiterleiten und das Reckteck entsprechend verschieben.


----------



## keram (5. Okt 2015)

1. Ich habe die paint Methode überschrieben und das Graphics Element g.fillRect eingefügt.
2. Ich will eine Hashmap erstellen und jedem fillRect einen Namen zuweisen.
3. Ich möchte die Rechtecke aus einem Bereich in den nächsten Bereich verschieben, die Bereiche befinden sich auf einem JPanel
4. Sobald man eines der Rechtecke, welche auf dem Panel gezeichnet sind, anheben und verschieben können. Genau so wollte ich das auch machen, leider weiß ich nicht wie ich die Rechtecke "aufheben" kann.


----------



## InfectedBytes (5. Okt 2015)

Du solltest dir eine Rechteck Klasse schreiben, welche x,y,breite,höhe und ggf. sowas wie farbe speichert.
Dann könntest du dir eine Liste (z.b. ArrayList) erstellen, in der du deine ganzen verschiedenen Rechteck Objekte speicherst. In der paint methode iterierst du dann über die liste und zeichnest ein entsprechendes Rechteck. 
Beim mouseclick kannst du dann auch durch die liste gehen und prüfen ob eines der Rechtecke angeklickt wurde.


----------



## Flown (5. Okt 2015)

Um das hier abzukürzen, ich hatte mal vor Jahren hier einen Code geschrieben für sowas:


Spoiler: Code





```
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class UITest {
	
	public static void main(String... args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				new UITest();
			}
		});
	}
	
	public UITest() {
		JFrame frame = new JFrame("Circles");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocationByPlatform(true);
		
		frame.add(new MyCanvas());
		frame.setSize(800, 600);
		frame.setVisible(true);
	}
}

class MyCanvas extends JPanel {
	private static final long serialVersionUID = 1L;
	private List<Drawable> drawables = Collections.synchronizedList(new ArrayList<>());
	
	public MyCanvas() {
		MouseAdapter adapter = new MouseAdapter() {
			private Drawable dragged = null;
			
			@Override
			public void mouseClicked(MouseEvent e) {
				drawables.add(new Circle(e.getX(), e.getY()));
				repaint();
			}
			
			@Override
			public void mousePressed(MouseEvent e) {
				Drawable d = null;
				for (Drawable drawable : drawables) {
					if (drawable.isIn(e.getX(), e.getY())) {
						d = drawable;
						break;
					}
				}
				if (d != null) {
					dragged = d;
				}
			}
			
			@Override
			public void mouseDragged(MouseEvent e) {
				if(dragged != null) {
					dragged.setPosition(e.getX(), e.getY());
					repaint();
				}
			}
			
			@Override
			public void mouseReleased(MouseEvent e) {
				dragged = null;
			}
		};
		addMouseListener(adapter);
		addMouseMotionListener(adapter);
	}
	
	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (g instanceof Graphics2D) {
			((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		}
		for (Drawable drawable : drawables) {
			drawable.draw(g);
		}
	}
}

interface Drawable {
	int getX();
	
	int getY();
	
	void setX(int x);
	
	void setY(int y);
	
	void setPosition(int x, int y);
	
	boolean isIn(int x, int y);
	
	void draw(Graphics g);
}

class Circle implements Drawable {
	
	public static final int DEFAULT_R = 50;
	
	private int x, y;
	private int r;
	private Color color;
	
	public Circle(int x, int y) {
		this(x, y, DEFAULT_R);
	}
	
	public Circle(int x, int y, int r) {
		this.x = x;
		this.y = y;
		this.r = r;
		Random rand = new Random();
		this.color = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(),
				0.5f + rand.nextFloat() * 0.5f);
	}
	
	@Override
	public void draw(Graphics g) {
		Color prev = g.getColor();
		g.setColor(color);
		g.fillOval(x - (r >>> 1), y - (r >>> 1), r, r);
		g.setColor(prev);
	}
	
	@Override
	public boolean isIn(int x, int y) {
		int dx = this.x - x;
		int dy = this.y - y;
		return r >= Math.sqrt(dx * dx + dy * dy);
	}
	
	@Override
	public int getX() {
		return x;
	}
	
	@Override
	public int getY() {
		return y;
	}
	
	@Override
	public void setX(int x) {
		this.x = x;
	}
	
	@Override
	public void setY(int y) {
		this.y = y;
	}
	
	@Override
	public void setPosition(int x, int y) {
		setX(x);
		setY(y);
	}
}
```


----------



## Sogomn (5. Okt 2015)

Wozu _HashMap_? Erstelle dir, wie InfectedBytes schon gesagt hat, eine Klasse für das Rechteck.


```
final class DragRectangle {

   private int x, y;
   private int width, height;

   private String name;
   private Color color;

   private static final String NO_NAME = "";

   public DragRectangle(final int x, final int y, final int width, final int height, final String name) {
      this.x = x;
      this.y = y;
      this.width = width;
      this.height = height;
      this.name = name;

      color = Color.BLACK;
   }

   public DragRectangle(final int x, final int y, final int width, final int height) {
      this(x, y, width, height, NO_NAME);
   }

   public void draw(final Graphics2D g) {
      //...
   }

   public boolean contains(final int xPos, final int yPos) {
      //...
   }

   /*Setters, getters*/

}
```

Dann brauchst Du nur eine Liste, welche wesentlich schneller ist als eine _Map_.


----------



## keram (6. Okt 2015)

Ersteinmal danke für die Antworten.
Jedoch habe ich nun noch einige Verständnisfragen.
Ich schreibe mir nun eine Methode welche mir die Rechtecke zeichnet. Dabei speicher ich alle Eigenschaften der einzelnen Rechtecke in eine Liste. Im MouseDraged event mache ich ein repaint um alle Rechtecke zu zeichnen die in der Liste sind und passe die Position des zu bewegenden Rechtecke im MouseDraged event an?


----------



## Sogomn (6. Okt 2015)

keram hat gesagt.:


> Ersteinmal danke für die Antworten.
> Jedoch habe ich nun noch einige Verständnisfragen.
> Ich schreibe mir nun eine Methode welche mir die Rechtecke zeichnet. Dabei speicher ich alle Eigenschaften der einzelnen Rechtecke in eine Liste. Im MouseDraged event mache ich ein repaint um alle Rechtecke zu zeichnen die in der Liste sind und passe die Position des zu bewegenden Rechtecke im MouseDraged event an?


Ich verstehe die Frage nicht ganz.


----------

