I'm currently working on a map generation program for a game I'm creating, and so I'm trying to be able to modify the individual tiles on the map using my mouse. I've successfully implemented the ability to click on a tile and change its value (from say a 4 way tile to a 2 way tile), but I am having trouble getting mouseDragged to work. According to the Java docs I've done the correct implementation of the mouseDragged interface into my MouseEventHandler, but I when I drag my mouse and move my mouse around neither of those events trip and throw the println text that I've got them throwing right now. If anyone could shed some light as to why this isn't working for me, I'd love that. Thanks!
A side question: If anyone has any better methods of trying to generate a map like this, or any (presumably anything is better than what I did) other methods of detecting individual mousePressed on a tile, I'd love to hear it. This is only my first time working with this sort of thing so I'm quite inexperienced and would love some advice.
As for the code itself:
File 1: OneQuestMapgen.java
package OneQuestMapgen;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.*;
import tiles.Tile;
import tiles.TileSet;
public class OneQuestMapgen extends JApplet{
/**
*
*/
public static OneQuestMapgen instance;
ArrayList<ArrayList<Tile>> map = new ArrayList<ArrayList<Tile>>();
TileSet tileSet = new TileSet();
public void init(){
this.setSize(950,600);
}
public void start(){
this.addMouseListener(new MouseEventListener(this));
int tileSize = tileSet.get("grasslands")[1].getHeight();
for (int i = 0; i < getHeight(); i += tileSize) {
ArrayList<Tile> temp = new ArrayList<Tile>();
for (int j = 0; j < getWidth(); j += tileSize) {
temp.add(new Tile(j, i, tileSize, tileSet.get("grasslands")));
}
map.add(temp);
}
}
public void paint(Graphics g){
for (int i = 0; i < map.size(); i++){
for(int j = 0; j < map.get(i).size(); j++){
map.get(i).get(j).render(g);
}
}
}
public void stop(){
}
public void destroy(){
}
public ArrayList<ArrayList<Tile>> getMap(){
return map;
}
}
File 2: MouseEventListener.java
package OneQuestMapgen;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import tiles.Tile;
public class MouseEventListener implements MouseListener, MouseMotionListener {
OneQuestMapgen instance;
ArrayList<ArrayList<Tile>> map;
public MouseEventListener(OneQuestMapgen instance) {
this.instance = instance;
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println(e.getX() + " , " + e.getY());
map = instance.getMap();
for (int i = 0; i < map.size(); i++) {
for (int j = 0; j < map.get(i).size(); j++)
if (map.get(i).get(j).bounds(e)) {
map.get(i).get(j).onClicked(instance.getGraphics());
}
}
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent arg0) {
System.out.println("Mouse Dragged: " + arg0.getX() + " , " + arg0.getY());
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
System.out.println("Mouse Moved: " + arg0.getX() + " , " + arg0.getY());
}
}
File 3: Tile.java
package tiles;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
@SuppressWarnings("serial")
public class Tile extends Square {
BufferedImage[] tiles;
int tileValue = 0;
public Tile (int x, int y, int size, BufferedImage[] tileSet){
super(x,y,size);
tiles = tileSet;
}
public void render(Graphics g) {
g.drawImage(tiles[tileValue], getX(), getY(), getDimension(), getDimension(), null);
}
public void onClicked(Graphics g) {
tileValue++;
System.out.println(tileValue);
g.drawImage(tiles[tileValue], getX(), getY(), getDimension(), getDimension(), null);
}
public boolean bounds(MouseEvent e){
if (e.getX() <= getX() + getDimension() && e.getX() >= getX() && e.getY() <= getY() + getDimension() && e.getY() >= getY())
return true;
return false;
}
}
File 4: TileSet.java
package tiles;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import javax.imageio.ImageIO;
public final class TileSet {
ConcurrentHashMap<String, BufferedImage[]> container = new ConcurrentHashMap<String, BufferedImage[]>(11);
BufferedImage[] grasslands = new BufferedImage[11];
public TileSet(){
boolean toAdd = true;
try {
grasslands[0] = ImageIO.read(new URL("http://i675.photobucket.com/albums/vv118/va023/OneQuest/GrassBlank_zpse99de845.png"));
grasslands[1] = ImageIO.read(new URL("http://i675.photobucket.com/albums/vv118/va023/OneQuest/4WayTile_zps49ebbeea.png"));
grasslands[2] = ImageIO.read(new URL("http://i675.photobucket.com/albums/vv118/va023/OneQuest/LineHorizontal_zpsc7bd45d5.png"));
grasslands[3] = ImageIO.read(new URL("http://i675.photobucket.com/albums/vv118/va023/OneQuest/LineVertical_zps9719b63f.png"));
grasslands[4] = ImageIO.read(new URL("http://i675.photobucket.com/albums/vv118/va023/OneQuest/TShapeTop_zpsa4b2aaa1.png"))
}
catch (Exception e) {
System.out.println("Unable to load resources for Grasslands");
}
for (int i = 0; i < grasslands.length; i++)
if (grasslands[i].getWidth() != grasslands[i].getHeight()) {
System.out.println("Error, tiles are not square. Grasslands has not been added.");
toAdd = false;
}
if (toAdd) {
container.put("grasslands".toLowerCase(), grasslands);
}
}
public BufferedImage[] get(String s) {
return container.get(s.toLowerCase());
}
}
File 5: Square.java
package tiles;
import javax.swing.JLabel;
public abstract class Square extends JLabel{
/**
*
*/
private static final long serialVersionUID = 1L;
private int x;
private int y;
private int dimension;
public Square(int x, int y, int dimension){
this.x = x;
this.y = y;
this.dimension = dimension;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getDimension(){
return dimension;
}
}
Note: If you would rather be able to pull it all off of github, I've added a link to my github repo for this project below:
URL: https://github.com/vagrawal1/OneQuestMapgen
HTTPS: https://github.com/vagrawal1/OneQuestMapgen.git
SSH: [email protected]:vagrawal1/OneQuestMapgen.git
Git Read-Only: git://github.com/vagrawal1/OneQuestMapgen.git
Thanks once again for your help and thank you for taking the time to read this.
You need to add a MouseMotionListener for dragging to work. You're just adding a MouseListener.
i.e.,
public void start() {
MouseEventListener myMouseEventListener = new MouseEventListener(this);
addMouseListener(myMouseEventListener);
addMouseMotionListener(myMouseEventListener);
//this.addMouseListener(new MouseEventListener(this));
Also as per my comments, your getX() and getY() methods of the Square class override the same methods of JLabel, and that if you aren't careful with these and use them correctly they can totally mess up the placement of your components in the GUI. Myself, I take great pains to avoid overriding these very methods. Consider changing their names if overriding wasn't your intention.
Also, I tend to favor mousePressed(...)
over the mouseClicked(...)
method as the former will respond to the press even if you move the mouse after pressing it.
Edit: another bug! You should almost never get your Graphics instance by calling getGraphics()
on a component as the Graphics object returned is evanescent and may soon become null. Instead either draw on a BufferedImage which is displayed in a JComponent or JPanel's paintComponent(...)
or just draw in paintComponent(...)
itself.
Edit 2: why override paint(...)
? That seems a bit dangerous to me, especially since you're not calling the super method, and especially since there is no need to do this sort of thing.