Package de.axxeed.animosy.gui

Source Code of de.axxeed.animosy.gui.MapPanel$DoubleClickListener

package de.axxeed.animosy.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
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.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.text.NumberFormat;
import java.util.Set;

import javax.swing.AbstractAction;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.Timer;

import org.apache.log4j.Logger;

import de.axxeed.animosy.model.BoardModel;
import de.axxeed.animosy.model.Game;
import de.axxeed.animosy.model.Manager;
import de.axxeed.animosy.model.Move;



/**
* @author Markus J. Luzius
* Created 25.04.2006 18:14:09
*
*/
public class MapPanel extends JPanel implements MouseListener, MouseMotionListener, MouseWheelListener {

  private static final long serialVersionUID = -6456650170894306985L;
  private static Logger log = Logger.getLogger(MapPanel.class);
  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 Board boardUI = new Board();
  private double scale = 1.0;
 
  private static final int PULSE_TIME = 150;

  Timer pulseTimer = new Timer(PULSE_TIME, new PulseListener());

  public MapPanel() {
    init();
  }
 
  public void init() {
    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);
    this.addMouseWheelListener(this);
    this.addKeyListener(GUIEventListener.getInstance());
  }

  public void updatePositions() {
    boardUI.setChanged();
    this.repaint();
  }
 
  private void switchFitToScreenSize() {
    if(!isToFit) {
      double xs = (double) this.getWidth() / boardUI.getImage().getWidth();
      double ys = (double) this.getHeight() / boardUI.getImage().getHeight();
      if(xs<ys) {
        scale = xs;
      }
      else {
        scale = ys;
      }
    }
    else {
      scale = 1.0;
    }
    isToFit = !isToFit;
    log.debug("New scale factor: "+scale);
    updateOffset(0, 0);
  }
 
  public double getZoom() {
    return scale;
  }
 
  public String getZoomInfo() {
    NumberFormat nf = NumberFormat.getInstance();
    nf.setMaximumFractionDigits(2);
    nf.setMinimumFractionDigits(2);
    return nf.format(scale*100)+"%";
  }

  public Image getMiniImage(int w, int h) {
    double scale = getMiniImageZoom(w, h);
    return boardUI.getImage().getScaledInstance((int) (boardUI.getImage().getWidth()*scale), (int) (boardUI.getImage().getHeight()*scale), BufferedImage.SCALE_FAST);
  }

  public double getMiniImageZoom(int w, int h) {
    double dx = (double) w / boardUI.getImage().getWidth();
    double dy = (double) h / boardUI.getImage().getHeight();
    return Math.min(dx, dy);
  }

  private void updateOffset(int x, int y) {
    if(isToFit) {
      PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
      return;
    }
    int pixX = (int)((double) this.getWidth() / scale);
    int pixY = (int)((double) this.getHeight() / scale);

    int maxX = boardUI.getImage().getWidth();
    int maxY = boardUI.getImage().getHeight();
    if(!isToFit) {
      // log.debug("changing offset: "+x+"/"+y);
      offset.translate(x, y);
      if(offset.x>maxX-pixX) {
        offset.x = Math.max(0, maxX-pixX);
      }
      else if(offset.x<0) {
        offset.x = 0;
      }
      if(offset.y>maxY-pixY) {
        offset.y = Math.max(0, maxY-pixY);
      }
      else if(offset.y<0) {
        offset.y = 0;
      }
    }
    PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
    this.repaint();
  }
 
  public Point getOffset() {
    return offset;
  }
 
  public void paintComponent ( Graphics g )
    {
    super.paintComponent(g);
//    long ts = System.currentTimeMillis();
   
    if(boardUI==null) return;
    int state = Manager.getGame().getState();
    if(state>Game.MOVE_MRX && state<Game.WIN_MRX && !pulseTimer.isRunning()) {
      pulseTimer.start();
    }
    else if((state==Game.MOVE_MRX || state==Game.NO_GAME || state==Game.WIN_MRX) && pulseTimer.isRunning()) {
      pulseTimer.stop();
    }
    else if(state==Game.WIN_DET) {
      pulseTimer.setDelay(PULSE_TIME * 5);
    }
   
    // log.debug("Painting map ("+this.getWidth()+"x"+this.getHeight()+")...");
    Graphics2D g2d = (Graphics2D) g;

    BufferedImage mapImage = boardUI.getImage();
   
    AffineTransform at;
    // System.out.println("scale factor: "+scale);
    at = AffineTransform.getScaleInstance(scale, scale);
   
    int pixX = (int)((double) this.getWidth() / scale);
    int pixY = (int)((double) this.getHeight() / scale);
    // log.debug("Max image size on screen ("+this.getWidth()+"/"+this.getHeight()+") with current zoom: "+pixX+"/"+pixY);

    if(pixX>mapImage.getWidth() && pixY>mapImage.getHeight()) {
      g2d.drawImage (mapImage, new AffineTransformOp(at, null), 0, 0);
    }
    else if(pixX>mapImage.getWidth()) {
      g2d.drawImage (mapImage.getSubimage(0, offset.y, mapImage.getWidth(), pixY), new AffineTransformOp(at, null), 0, 0);
    }
    else if(pixY>mapImage.getHeight()) {
      g2d.drawImage (mapImage.getSubimage(offset.x, 0, pixX, mapImage.getHeight()), new AffineTransformOp(at, null), 0, 0);
    }
    else {
      int maxX = pixX;
      int maxY = pixY;
      if(mapImage.getWidth()<maxX) maxX = mapImage.getWidth()-1;
      if(mapImage.getHeight()<maxY) maxY = mapImage.getHeight()-1;
      g2d.drawImage (mapImage.getSubimage(offset.x, offset.y, maxX, maxY), new AffineTransformOp(at, null), 0, 0);
    }
   
    g2d.dispose();
    // log.debug("mapPanel: "+(System.currentTimeMillis()-ts)+"ms");

   
    }

  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 DoubleClickListener(new Point(e.getX(), e.getY())));
        timer.start();
      }
    }
    else {
      int pos = boardUI.getPos((int)(scale*(e.getPoint().x+offset.x)), (int)(scale*(e.getPoint().y+offset.y)));
     
      int state = Manager.getGame().getState();
      if(pos>0 && state>Game.MOVE_MRX && state<Game.WIN_MRX) {
        JPopupMenu popup = new JPopupMenu();
        if(Manager.getGame().getActiveDetective().canMoveTo(pos)) {
          Set<Move> possibleMoves = Manager.getGame().getBoard().getDetectives()[state-1].getPossibleMoves();
//          log.debug("Moves for detective ["+state+"]: "+possibleMoves);
          for(Move m: possibleMoves) {
            log.debug("node "+m.getNode()+", pos="+pos);
            if(m.getNode()!=pos) continue;
            StringBuilder linkText = new StringBuilder();
            linkText.append("move to ").append(m.getNode()).append(" (");
            switch(m.getType()) {
              case BoardModel.TAXI: linkText.append("TAXI").append(")"); break;
              case BoardModel.BUS: linkText.append("BUS").append(")"); break;
              case BoardModel.UG: linkText.append("UG").append(")"); break;
              case BoardModel.BLACK: break;
              case BoardModel.INF: linkText.append("INF").append(")"); break;
              default: linkText.append("???").append(")"); break;
            }
           
            // detectiveMenu.add( new JMenuItem(linkText.toString()) );
            AbstractAction action = new AbstractAction(linkText.toString())
              {
                private static final long  serialVersionUID  = -4379938472159497577L;
                public void actionPerformed( ActionEvent e ) {
                  log.debug("Selected move: "+((Move)this.getValue(e.getActionCommand())));
                  Manager.getGame().moveDetective((Move)this.getValue(e.getActionCommand()));
                  PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
                }
              };
            action.putValue(linkText.toString(), m);
            action.putValue("Detective", Manager.getGame().getBoard().getDetectives()[state-1]);
            popup.add( action );
          }
        }
        else {
          JMenuItem item = new JMenuItem("can't move to ["+pos+"]");
          item.setEnabled(false);
          popup.add(item);
        }
       
        if (popup != null) {
          popup.show(e.getComponent(), e.getX(), e.getY());
        }
       
      }
//      FIXME here I am!!!! xx
     
      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) {
    if(e.getButton()==1) {
      log.debug("Setting initial drag point..."+e.getPoint());
      prevPos.setLocation(e.getPoint());
    }
  }

  public void mouseReleased(MouseEvent e) {
    // log.debug("dragging is over!");
    prevPos.setLocation(-1, -1);
  }

  public void mouseDragged(MouseEvent arg0) {
    // 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 DoubleClickListener implements ActionListener {
    private Point pos;
    public DoubleClickListener(Point p) {
      pos = p;
    }
    public void actionPerformed(ActionEvent e) {
      ((Timer) e.getSource()).stop();
      if(isDoubleclick) {
        isDoubleclick = false;
      }
      else {
        log.debug("Single click on left mouse button at pos "+pos+"...");
        PanelRepository.get(PanelRepository.STATUS_PANEL).repaint();
      }
    }
  }
 
  private class PulseListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      boardUI.pulse();
      boardUI.setChanged();
      repaint();
    }
  }

  public void mouseWheelMoved(MouseWheelEvent mwe) {
    isToFit = false;
    if(mwe.getWheelRotation()<0) {
      // shrink
      if(scale*10!=Math.rint(scale*100)) {
        scale = Math.rint((scale-0.05)*100.) / 100.;
      }
      else {
        scale-=0.01;
      }
      if(scale<0.3) scale = 0.3;
    }
    else {
      // blow up
      if(scale*10!=Math.rint(scale*100)) {
        scale = Math.rint((scale+0.05)*100.) / 100.;
      }
      else {
        scale+=0.01;
      }
      if(scale>1.5) scale = 1.5;
    }
    // log.debug("New scale factor: "+scale);
    updateOffset(0, 0);
   
  }

}
TOP

Related Classes of de.axxeed.animosy.gui.MapPanel$DoubleClickListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.