package de.axxeed.animosy.sandbox;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.apache.log4j.Logger;
/**
* @author Markus J. Luzius
* Created 25.04.2006 18:14:09
*
*/
public class MapPanel extends JPanel implements MouseListener, MouseMotionListener {
private static final long serialVersionUID = -6456650170894306985L;
private static Logger log = Logger.getLogger(MapPanel.class);
private static BufferedImage mapImage = null;
private static Point offset = new Point(0,0);
private boolean isToFit = false;
private Point prevPos = new Point(-1, -1);
private long timeFirstClick = -1;
private boolean isDoubleclick = false;
private static final long dblClickTimeMs = 250;
private Point boxPos = null;
public MapPanel() {
init();
}
public void init() {
if(mapImage==null) mapImage = loadMapImage();
this.setBackground(Color.LIGHT_GRAY);
// this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
this.setMinimumSize(new Dimension(300,250));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void switchFitToScreenSize() {
isToFit = !isToFit;
}
private void updateOffset(int x, int y) {
if(!isToFit) {
// log.debug("changing offset: "+x+"/"+y);
offset.translate(x, y);
if(offset.x>mapImage.getWidth()-this.getWidth()) {
offset.x = mapImage.getWidth()-this.getWidth();
}
else if(offset.x<0) {
offset.x = 0;
}
if(offset.y>mapImage.getHeight()-this.getHeight()) {
offset.y = mapImage.getHeight()-this.getHeight();
}
else if(offset.y<0) {
offset.y = 0;
}
this.repaint();
}
}
private void setBoxPos(Point p) {
Graphics2D g2d = (Graphics2D) mapImage.getGraphics();
g2d.setColor(Color.RED);
g2d.drawRect(p.x, p.y, 20, 20);
}
public void paintComponent ( Graphics g )
{
super.paintComponent(g);
// log.debug("Painting map ("+this.getWidth()+"x"+this.getHeight()+")...");
Graphics2D g2d = (Graphics2D) g;
if(isToFit) {
AffineTransform at;
double xs = (double) this.getWidth() / mapImage.getWidth();
double ys = (double) this.getHeight() / mapImage.getHeight();
if(xs<ys) {
ys = xs;
}
else {
xs = ys;
}
System.out.println("scale factor: "+xs+"/"+ys);
at = AffineTransform.getScaleInstance(xs, ys);
Graphics2D g2 = (Graphics2D)g;
g2.drawImage(mapImage, new AffineTransformOp(at, null), 0, 0);
}
else {
g2d.drawImage (mapImage.getSubimage(offset.x, offset.y, this.getWidth(), this.getHeight()), null, 0, 0);
}
g2d.dispose();
}
private BufferedImage loadMapImage() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
File file = new File("bin/map.jpg");
// String l_filename = IMAGE_DIR + File.separator + filename;
log.debug("Loading image <"+file.getAbsolutePath()+">");
try {
BufferedImage bi = ImageIO.read(file);
int transparency = bi.getColorModel().getTransparency();
BufferedImage copy = gc.createCompatibleImage(bi.getWidth(), bi.getHeight(), transparency);
Graphics2D g2d = copy.createGraphics();
g2d.drawImage(bi,0,0,null);
g2d.dispose();
return copy;
}
catch (IOException e) {
log.warn("Error loading image file <"+file.getAbsolutePath()+">", e);
}
return null;
}
public void mouseClicked(MouseEvent e) {
// XXX Auto-generated method stub
if(e.getButton()==1) {
if(timeFirstClick>0 && System.currentTimeMillis()-timeFirstClick<dblClickTimeMs) {
// double click
isDoubleclick = true;
log.debug("Resizing map image... "+(System.currentTimeMillis()-timeFirstClick)+"ms");
switchFitToScreenSize();
this.repaint();
timeFirstClick = -1;
}
else {
timeFirstClick = System.currentTimeMillis();
// set timer for other action
Timer timer = new Timer((int) dblClickTimeMs+10, new TimerListener(new Point(e.getX(), e.getY())));
timer.start();
}
}
else {
timeFirstClick = -1;
}
}
public void mouseEntered(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mouseExited(MouseEvent e) {
// XXX Auto-generated method stub
}
public void mousePressed(MouseEvent e) {
// XXX Auto-generated method stub
log.debug("Setting initial drag point..."+e.getPoint());
prevPos.setLocation(e.getPoint());
}
public void mouseReleased(MouseEvent e) {
// XXX Auto-generated method stub
// log.debug("dragging is over!");
prevPos.setLocation(-1, -1);
}
public void mouseDragged(MouseEvent arg0) {
// XXX Auto-generated method stub
// log.debug("dragged..."+arg0.getX()+"/"+arg0.getY());
updateOffset(prevPos.x-arg0.getX(), prevPos.y-arg0.getY());
prevPos.setLocation(arg0.getPoint());
}
public void mouseMoved(MouseEvent arg0) {
// XXX Auto-generated method stub
if(timeFirstClick > 0) timeFirstClick = -1;
}
private class TimerListener implements ActionListener {
private Point pos;
public TimerListener(Point p) {
pos = p;
}
public void actionPerformed(ActionEvent e) {
if(isDoubleclick) {
isDoubleclick = false;
}
else {
setBoxPos(pos);
repaint();
}
((Timer) e.getSource()).stop();
}
}
}