package jas2.util.moverlayeredpane;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class MLPArrowFactory implements MLPObjectFactory {
	//
	//public interface methods
	//
	public void mousePressed(MouseEvent e, JPanel p) {
		dragStart = e.getPoint();
		tempArrow = new MovableArrow(dragStart, arrowHeadDrawState,
									 arrowHeadLength, arrowHeadFilled);
		tempArrow.setLocation(e.getPoint());
		//tempArrow.setBorder(BorderFactory.createLineBorder(Color.black));//debug
		p.add(tempArrow);
		tempArrow.setVisible(true);
	}
	public void mouseDragged(MouseEvent e, JPanel p) {
		updateArrowSizeAndLocation(tempArrow, e.getPoint());
		//repainting just a rect is more efficient but it
		//doesn't work very well, so every FULL_REPAINT times
		//we do a (guess what!) full repaint
		if (((++numRepaints) % FULL_REPAINT) == 0) {
			p.repaint();
		} else {
			p.repaint(
				new Rectangle(
					dragStart.x - REPAINT_FUDGE_FACTOR,
					dragStart.y - REPAINT_FUDGE_FACTOR,
					e.getPoint().x - dragStart.x + 2*REPAINT_FUDGE_FACTOR,
					e.getPoint().y - dragStart.y + 2*REPAINT_FUDGE_FACTOR));
		}
	}
	public void mouseReleased(MouseEvent e, JPanel p) {
		p.repaint();
	}
	//
	//other public methods
	//
	public int getArrowHeadDrawState() {
		return arrowHeadDrawState;
	}
	public void setArrowHeadDrawState(int newState) {
		arrowHeadDrawState = newState;
	}
	public float getArrowHeadLength() {
		return arrowHeadLength;
	}
	public void setArrowHeadLength(float newLength) {
		arrowHeadLength = newLength;
	}
	public boolean getArrowHeadFillState() {
		return arrowHeadFilled;
	}
	public void setArrowHeadFillState(boolean newState) {
		arrowHeadFilled = newState;
	}
	/**
	 * //!PA - implement
	 * I'm not sure if this class is the right place for this; basically we need to pop up a
	 * dialog box asking for params for the arrow (size, filled, etc)...
	 */
	public void showArrowConfigDialog() {
	}
	//
	//public constants
	//
	public interface ArrowheadDrawStates {
		int NONE = 0, FINISH = 1, START = 2, BOTH = 3;
	}

	//
	//private methods
	//
	
	/**
	 * Even though the start point is fixed, we might need to change the
	 * location of the tempArrow.  Note that the arrow always goes between
	 * 2 diagonally opposite corners of the tempArrow.  However, WHICH corners
	 * it goes between are not fixed.
	 */
	private void updateArrowSizeAndLocation(MovableArrow p_arrow, Point p_newFinish) {
		//System.out.println("updateArrowSizeAndLocation");
		Point start = p_arrow.getStart();
		p_arrow.updateFinish(p_newFinish);
		if (start.x < p_newFinish.x) {
			if (start.y < p_newFinish.y) {
				p_arrow.setLocation(start.x, start.y);
			} else {
				p_arrow.setLocation(start.x, p_newFinish.y);
			}
		} else {
			if (start.y < p_newFinish.y) {
				p_arrow.setLocation(p_newFinish.x, start.y);
			} else {
				p_arrow.setLocation(p_newFinish.x, p_newFinish.y);
			}
		}
		int buf = p_arrow.getArrowHeadBuffer();
		p_arrow.setLocation(p_arrow.getLocation().x - buf, p_arrow.getLocation().y - buf);
		p_arrow.setSize((Math.abs(p_arrow.getStart().x - p_arrow.getFinish().x) + 2*buf),
						(Math.abs(p_arrow.getStart().y - p_arrow.getFinish().y) + 2*buf));
		//who cares if our components can get partially past the edge of the
		//window, the part of them that does is invisible!
		p_arrow.updateThetaAndArrowHeads();
		p_arrow.invalidate();
	}
	
	//
	//private member variables
	//
	private int arrowHeadDrawState;
	private MovableArrow tempArrow;
	private boolean arrowHeadFilled;
	private float arrowHeadLength = 15.0f;
	private Point dragStart;
	private int numRepaints = 0;
	private static final int REPAINT_FUDGE_FACTOR = 10;
	private static final int FULL_REPAINT = 5;
}

 

Ads help maintain this website.