package gui;
import gui.options.JMShapePropertyDialog;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import shapes.Circle;
import shapes.Poly;
import shapes.Rect;
import shapes.Shape;
public class JMImagePanel extends JPanel implements MouseListener,
MouseMotionListener, KeyListener, ActionListener {
public static final int SELECT_MOVE = 4;
public static final int EDIT = 5;
public static final int CREATE = 3;
public static final int CREATE_CIRCLE = 0;
public static final int CREATE_RECT = 1;
public static final int CREATE_POLY = 2;
private int createMode = 0;
private int mode = 3;
public int startRad = 0;
private boolean freeHand = false;
public static Color polySelectedColor = new Color(255, 100, 100, 150);
public static Color polyUnselectedColor = new Color(100, 100, 255, 150);
public static Color rectSelectedColor = new Color(255, 100, 100, 150);
public static Color rectUnselectedColor = new Color(100, 100, 255, 150);
public static Color circleSelectedColor = new Color(255, 100, 100, 150);
public static Color circleUnselectedColor = new Color(100, 100, 255, 150);
public static boolean ctrlPressed = false;
private int startX;
private int startY;
private int moveX;
private int moveY;
JMFrame parent;
ArrayList<Circle> circles = new ArrayList<Circle>();
ArrayList<Rect> rects = new ArrayList<Rect>();
ArrayList<Poly> polys = new ArrayList<Poly>();
public boolean creatingPoly;
// private boolean shapeSelected = false;
private int buttonID;
private boolean shifting;
private boolean clickingAlreadyClicked;
private boolean mouseDown;
private int selectionX;
private int selectionY;
public static Color circleSelectedOutlineColor = Color.red;
public static Color rectSelectedOutlineColor = Color.red;
public static Color circleUnselectedOutlineColor = Color.black;
public static Color rectUnselectedOutlineColor = Color.black;
public static Color polyUnselectedOutlineColor = Color.black;
public static Color polySelectedOutlineColor = Color.red;
public static boolean shiftPressed = false;
public JMImagePanel(JMFrame parent) {
this.parent = parent;
this.setPreferredSize(new Dimension(this.parent.getWidth() - 110,
this.parent.getHeight() - 50));
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this);
this.setFocusable(true);
this.setBackground(Color.lightGray);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.white);
for (int i = 0; i < (this.getWidth() / 20) + 1; i++) {
for (int j = 0; j < (this.getHeight() / 20) + 1; j++) {
g.fillRect(i * 20, j * 20, 10, 10);
}
}
for (int i = 0; i < (this.getWidth() / 20) + 1; i++) {
for (int j = 0; j < (this.getHeight() / 20) + 1; j++) {
g.fillRect(i * 20 + 10, j * 20 + 10, 10, 10);
}
}
parent.imageIcon.paintIcon(this, g, 0, 0);
g.setColor(Color.black);
g.drawRect(0, 0, parent.imageIcon.getIconWidth(), parent.imageIcon
.getIconHeight());
g.setColor(circleUnselectedColor);
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).getSelected()) {
g.setColor(circleSelectedColor);
}
g.fillOval(circles.get(i).getX(), circles.get(i).getY(), circles
.get(i).getRadius() * 2, circles.get(i).getRadius() * 2);
if (circles.get(i).getSelected()) {
g.setColor(circleSelectedOutlineColor);
} else {
g.setColor(circleUnselectedOutlineColor);
}
g.drawOval(circles.get(i).getX(), circles.get(i).getY(), circles
.get(i).getRadius() * 2, circles.get(i).getRadius() * 2);
g.setColor(circleUnselectedColor);
}
g.setColor(rectUnselectedColor);
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).selected)
g.setColor(rectSelectedColor);
g.fillRect(rects.get(i).getX(), rects.get(i).getY(), rects.get(i)
.getWidth(), rects.get(i).getHeight());
if (rects.get(i).selected) {
g.setColor(rectSelectedOutlineColor);
} else {
g.setColor(rectUnselectedOutlineColor);
}
g.drawRect(rects.get(i).getX(), rects.get(i).getY(), rects.get(i)
.getWidth(), rects.get(i).getHeight());
g.setColor(rectUnselectedColor);
}
g.setColor(polyUnselectedColor);
for (int i = 0; i < polys.size(); i++) {
if (polys.get(i).selected && this.mode != JMImagePanel.EDIT)
g.setColor(polySelectedColor);
g.fillPolygon((Polygon) polys.get(i).getShape());
g.setColor(polyUnselectedOutlineColor);
g.drawPolygon(polys.get(i).getShape());
try {
for (int j = 0; j < polys.get(i).getShape().npoints; j++) {
if (polys.get(i).pointSelected[j])
g.setColor(polySelectedOutlineColor);
g.fillRect(polys.get(i).getShape().xpoints[j] - 1, polys
.get(i).getShape().ypoints[j] - 1, 3, 3);
g.setColor(Color.black);
}
} catch (NullPointerException n) {
}
g.setColor(polyUnselectedColor);
}
if(this.mouseDown){
g.setColor(Color.black);
int width = Math.abs(this.startX - this.selectionX);
int height = Math.abs(this.startY - this.selectionY);
g.drawRect(Math.min(this.startX, this.selectionX), Math.min(this.startY, this.selectionY), width, height);
}
}
public int getMode() {
return this.mode;
}
public void setMode(int mode) {
this.mode = mode;
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
this.startX = this.moveX = this.selectionX = e.getX();
this.startY = this.moveY = this.selectionY = e.getY();
this.mouseDown = true;
this.buttonID = e.getButton();
if (this.mode == JMImagePanel.SELECT_MOVE
|| this.mode == JMImagePanel.EDIT) {
boolean clickSelected = false;
for (int i = 0; i < this.circles.size(); i++) {
if (this.circles.get(i).contains(e.getPoint())
&& this.circles.get(i).selected) {
clickSelected = true;
}
}
for (int i = 0; i < this.rects.size(); i++) {
if (this.rects.get(i).contains(e.getPoint())
&& this.rects.get(i).selected) {
clickSelected = true;
}
}
for (int i = 0; i < this.polys.size(); i++) {
if (((Polygon) this.polys.get(i).getShape()).contains(e
.getPoint())
&& this.polys.get(i).selected) {
clickSelected = true;
}
}
if (!(clickSelected || shiftPressed)) {
setAllSelected(false);
}
for (int i = 0; i < this.circles.size(); i++) {
if (this.circles.get(i).contains(e.getPoint())) {
this.circles.get(i).selected = true;
}
}
for (int i = 0; i < this.rects.size(); i++) {
if (this.rects.get(i).contains(e.getPoint())) {
this.rects.get(i).selected = true;
}
}
for (int i = 0; i < this.polys.size(); i++) {
if (((Polygon) this.polys.get(i).getShape()).contains(e
.getPoint())) {
this.polys.get(i).selected = true;
}
}
} else if (e.getButton() == MouseEvent.BUTTON1
&& this.mode == JMImagePanel.CREATE) {
if (this.createMode == JMImagePanel.CREATE_CIRCLE) {
circles.add(new Circle(new Point2D.Double(this.startX,
this.startY), 0));
} else if (this.createMode == JMImagePanel.CREATE_POLY) {
if (this.creatingPoly) {
polys.get(polys.size() - 1).addPoint(startX, startY);
} else {
int[] x = { this.startX };
int[] y = { this.startY };
polys.add(new Poly(x, y, 1));
this.creatingPoly = true;
}
} else if (e.getButton() != MouseEvent.BUTTON3
&& this.mode == JMImagePanel.CREATE
&& this.createMode == JMImagePanel.CREATE_RECT) {
rects.add(new Rect(this.startX, this.startY, 0, 0));
}
if (this.mode != JMImagePanel.CREATE
|| this.createMode != JMImagePanel.CREATE_POLY) {
this.creatingPoly = false;
}
}
this.repaint();
refreshSource();
}
public Shape[] getSelected() {
int numSelected = 0;
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).selected)
numSelected++;
}
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).selected)
numSelected++;
}
for (int i = 0; i < polys.size(); i++) {
if (polys.get(i).selected)
numSelected++;
}
Shape[] selected = new Shape[numSelected];
int index = 0;
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).selected) {
selected[index] = circles.get(i);
index++;
}
}
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).selected) {
selected[index] = rects.get(i);
index++;
}
}
for (int i = 0; i < polys.size(); i++) {
if (polys.get(i).selected) {
selected[index] = polys.get(i);
index++;
}
}
return selected;
}
public void setCreateMode(int createMode) {
this.createMode = createMode;
}
public void mouseReleased(MouseEvent e) {
this.moveX = this.startX = this.selectionX = 0;
this.moveY = this.startY = this.selectionY = 0;
this.mouseDown = false;
if (circles.size() > 0
&& (circles.get(circles.size() - 1).getRadius() == 0))
circles.remove(circles.size() - 1);
if (rects.size() > 0
&& (rects.get(rects.size() - 1).getWidth() == 0 || rects.get(
rects.size() - 1).getHeight() == 0))
rects.remove(rects.size() - 1);
this.repaint();
}
public void mouseDragged(MouseEvent e) {
if (this.mode == JMImagePanel.SELECT_MOVE) {
boolean shapeSelected = false;
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).selected) {
circles.get(i).move(e.getX() - this.moveX,
e.getY() - this.moveY);
// System.out.println("Move a circle" + e.getX() + " "
// + e.getY() + " " + this.startX + " " + this.startY);
shapeSelected = true;
}
}
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).selected)
rects.get(i).move(e.getX() - this.moveX,
e.getY() - this.moveY);
shapeSelected = true;
}
for (int i = 0; i < polys.size(); i++) {
if (polys.get(i).selected) {
polys.get(i).move(e.getX() - this.moveX,
e.getY() - this.moveY);
shapeSelected = true;
}
}
if(!shapeSelected){
if(!freeHand){
this.selectionX = e.getX();
this.selectionY = e.getY();
}else{
}
}
this.moveX = e.getX();
this.moveY = e.getY();
} else if (this.mode == JMImagePanel.EDIT) {
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).selected)
circles.get(i).setRadius(
(int) (e.getPoint().distance(circles.get(i)
.getCenter())));
}
for (int i = 0; i < rects.size(); i++) {
if (rects.get(i).selected) {
rects.get(i).setWidth(
((int) e.getPoint().getX() - rects.get(i).getX()));
rects.get(i).setHeight(
((int) e.getPoint().getY() - rects.get(i).getY()));
}
}
for (int i = 0; i < polys.size(); i++) {
polys.get(i).movePoint(polys.get(i).selected(),
e.getX() - this.moveX, e.getY() - this.moveY);
}
this.moveX = e.getX();
this.moveY = e.getY();
} else if (this.buttonID == MouseEvent.BUTTON3) {
} else {
if (this.mode == JMImagePanel.CREATE
&& this.createMode == JMImagePanel.CREATE_CIRCLE) {
circles.get(circles.size() - 1).setRadius(
(int) (e.getPoint().distance(new Point2D.Double(
this.startX, this.startY))));
} else if (this.mode == JMImagePanel.CREATE
&& this.createMode == JMImagePanel.CREATE_POLY) {
polys.get(polys.size() - 1).getShape().xpoints[polys.get(
polys.size() - 1).getShape().npoints - 1] = ((int) e
.getPoint().getX());
polys.get(polys.size() - 1).getShape().ypoints[polys.get(
polys.size() - 1).getShape().npoints - 1] = ((int) e
.getPoint().getY());
} else if (this.mode == JMImagePanel.CREATE
&& this.createMode == JMImagePanel.CREATE_RECT) {
rects.get(rects.size() - 1).setWidth(
((int) e.getPoint().getX() - this.startX));
rects.get(rects.size() - 1).setHeight(
((int) e.getPoint().getY() - this.startY));
}
}
this.refreshSource();
this.repaint();
}
public void refreshSource() {
String code = "";
code += "<map name=\"" + parent.mapName + "\">\n";
for (int i = 0; i < circles.size(); i++) {
code += "<area target=\"\" shape=\"circle\" href=\""
+ circles.get(i).link + "\" coords=\"";
code += (int) (circles.get(i).getCenter().getX()) + ",";
code += (int) (circles.get(i).getCenter().getY()) + ",";
code += circles.get(i).getRadius()
+ "\" "
+ (circles.get(i).onMouseOverb ? "onMouseOver=\""
+ circles.get(i).onMouseOver.replace("\"", "'")
+ "\" " : "")
+ (circles.get(i).onMouseOutb ? "onMouseOut=\""
+ circles.get(i).onMouseOut.replace("\"", "'")
+ "\" " : "")
+ (circles.get(i).onMouseDownb ? "onMouseDown=\""
+ circles.get(i).onMouseDown.replace("\"", "'")
+ "\" " : "")
+ (circles.get(i).onMouseUpb ? "onMouseUp=\""
+ circles.get(i).onMouseUp.replace("\"", "'")
+ "\" " : "") + "/>\n";
}
for (int i = 0; i < rects.size(); i++) {
code += "<area target=\"\" shape=\"rect\" href=\""
+ rects.get(i).link + "\" coords=\"";
code += rects.get(i).getX() + ",";
code += rects.get(i).getY() + ",";
code += rects.get(i).getX() + rects.get(i).getWidth() + ",";
code += rects.get(i).getY()
+ rects.get(i).getHeight()
+ "\" "
+ (rects.get(i).onMouseOverb ? "onMouseOver=\""
+ rects.get(i).onMouseOver.replace("\"", "'")
+ "\" " : "")
+ (rects.get(i).onMouseOutb ? "onMouseOut=\""
+ rects.get(i).onMouseOut.replace("\"", "'")
+ "\" " : "")
+ (rects.get(i).onMouseDownb ? "onMouseDown=\""
+ rects.get(i).onMouseDown.replace("\"", "'")
+ "\" " : "")
+ (rects.get(i).onMouseUpb ? "onMouseUp=\""
+ rects.get(i).onMouseUp.replace("\"", "'") + "\" "
: "") + "/>\n";
}
for (int i = 0; i < polys.size(); i++) {
code += "<area target=\"\" shape=\"poly\" href=\""
+ polys.get(i).link + "\" coords=\"";
code += polys.get(i).getShape().xpoints[0] + ",";
code += polys.get(i).getShape().ypoints[0];
for (int j = 1; j < polys.get(i).getShape().npoints; j++) {
code += "," + polys.get(i).getShape().xpoints[j];
code += "," + polys.get(i).getShape().ypoints[j];
}
code += "\" "
+ (polys.get(i).onMouseOverb ? "onMouseOver=\""
+ polys.get(i).onMouseOver.replace("\"", "'")
+ "\" " : "")
+ (polys.get(i).onMouseOutb ? "onMouseOut=\""
+ polys.get(i).onMouseOut.replace("\"", "'")
+ "\" " : "")
+ (polys.get(i).onMouseDownb ? "onMouseDown=\""
+ polys.get(i).onMouseDown.replace("\"", "'")
+ "\" " : "")
+ (polys.get(i).onMouseUpb ? "onMouseUp=\""
+ polys.get(i).onMouseUp.replace("\"", "'") + "\" "
: "");
code += "\"/>\n";
}
code += "</map>";
boolean i = true;
i = !i;
parent.sourcePanel.setText(code);
}
public void mouseMoved(MouseEvent e) {
}
public void keyPressed(KeyEvent e) {
if (KeyEvent.getKeyText(e.getKeyChar()).equals("Delete")) {
delete();
} else if (KeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase("x")
&& ctrlPressed) {
delete();
} else if (KeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase("a")
&& ctrlPressed) {
setAllSelected(true);
} else if (KeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase("a")
&& shiftPressed) {
addPoint();
} else if (KeyEvent.getKeyText(e.getKeyCode()).equals("Ctrl")) {
ctrlPressed = true;
} else if (KeyEvent.getKeyText(e.getKeyCode()).equals("Shift")) {
shiftPressed = true;
} else if (KeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase("l")
&& ctrlPressed) {
editLink();
} else if (KeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase("p")
&& ctrlPressed) {
shapeProps();
}
}
public void keyReleased(KeyEvent e) {
if (KeyEvent.getKeyText(e.getKeyCode()).equals("Ctrl")) {
ctrlPressed = false;
}
if (KeyEvent.getKeyText(e.getKeyCode()).equals("Shift")) {
shiftPressed = false;
}
}
public void keyTyped(KeyEvent e) {
}
public void delete() {
for (int i = circles.size() - 1; i >= 0; i--) {
if (circles.get(i).selected)
circles.remove(i);
}
for (int i = rects.size() - 1; i >= 0; i--) {
if (rects.get(i).selected)
rects.remove(i);
}
for (int i = polys.size() - 1; i >= 0; i--) {
if (polys.get(i).selected && this.mode != JMImagePanel.EDIT)
polys.remove(i);
else {
polys.get(i).deleteSelected(this.parent);
if (polys.get(i).getShape().npoints == 0)
polys.remove(i);
}
}
this.repaint();
this.refreshSource();
}
public void setAllSelected(boolean selected) {
for (int i = 0; i < circles.size(); i++) {
circles.get(i).selected = selected;
}
for (int i = 0; i < rects.size(); i++) {
rects.get(i).selected = selected;
}
for (int i = 0; i < polys.size(); i++) {
polys.get(i).selected = selected;
}
this.repaint();
}
public void addPoint() {
for (int i = 0; i < polys.size(); i++) {
if (polys.get(i).selected) {
polys.get(i).divide(polys.get(i).getSelectedPoints(),
this.parent);
}
}
this.repaint();
}
public void rightClickMenu(Point location) {
JPopupMenu j = new JPopupMenu();
j.setLocation(location);
JMenuItem link = new JMenuItem("Edit Link");
link.addActionListener(this);
link.setActionCommand("link");
j.add(link);
JMenuItem shapeProperties = new JMenuItem("Edit Shape Properties");
shapeProperties.addActionListener(this);
shapeProperties.setActionCommand("props");
j.add(shapeProperties);
j.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("props"))
shapeProps();
else if (e.getActionCommand().equals("link"))
editLink();
}
public void editLink() {
Shape[] selected = getSelected();
String origLink = selected[0].link;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].link.equals(origLink))
origLink = "";
}
String newLink = JOptionPane.showInputDialog(parent,
"Enter the new Link", origLink);
if (newLink != null)
for (int i = 0; i < selected.length; i++) {
selected[i].link = newLink;
}
refreshSource();
}
public void shapeProps() {
Shape[] selected = getSelected();
String origLink = selected[0].link;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].link.equals(origLink))
origLink = "";
}
String target = selected[0].target;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].target.equals(target))
target = "";
}
String mouseOver = selected[0].onMouseOver;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseOver.equals(mouseOver))
mouseOver = "";
}
String mouseOut = selected[0].onMouseOut;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseOut.equals(mouseOut))
mouseOut = "";
}
String mouseDown = selected[0].onMouseDown;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseDown.equals(mouseDown))
mouseDown = "";
}
String mouseUp = selected[0].onMouseUp;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseUp.equals(mouseUp))
mouseUp = "";
}
boolean mouseOverb = selected[0].onMouseOverb;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseOverb == (mouseOverb))
mouseOverb = false;
}
boolean mouseOutb = selected[0].onMouseOutb;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseOutb == (mouseOutb))
mouseOutb = false;
}
boolean mouseDownb = selected[0].onMouseDownb;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseDownb == (mouseDownb))
mouseDownb = false;
}
boolean mouseUpb = selected[0].onMouseUpb;
for (int i = 0; i < selected.length; i++) {
if (!selected[i].onMouseUpb == (mouseUpb))
mouseUpb = false;
}
new JMShapePropertyDialog(selected, origLink, target, mouseOverb,
mouseOver, mouseOutb, mouseOut, mouseDownb, mouseDown,
mouseUpb, mouseUp, this.parent);
}
}