/*
* Copyright (C) 2004 The Concord Consortium, Inc.,
* 10 Concord Crossing, Concord, MA 01742
*
* Web Site: http://www.concord.org
* Email: info@concord.org
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* END LICENSE */
/**
* <p>Title: JAnnotationImage</p>
* @author Dmitry Markman, dima@concord.org
* @version 1.0
*/
package org.concord.swing;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.util.LinkedList;
import java.util.ListIterator;
import org.concord.swing.JAnnotationImageModel.AnnotationSpot;
/**
* The class to hold and drawing annotation image data:
* annotation spot areas, annotations
* could be used with <code>JAnnotationImageContainer</code>
* @see JAnnotationImageContainer
*/
public class JAnnotationImage extends javax.swing.JPanel{
static final String START_DRAG_PROPERTY = "startDragPoint";
private int dragLimit = 20;
Draggable currentDraggable;
JAnnotationImageModel model;
ParentComponentTransformer draggableComponentTransformer;
ParentComponentTransformer draggableImageTransformer;
AnnotatedImageMouseListener annotatedImageMouseListener = new AnnotatedImageMouseListener();
AnnotatedImageMouseMotionListener annotatedImageMouseMotionListener = new AnnotatedImageMouseMotionListener();
java.util.HashMap properties = new java.util.HashMap();
boolean pointsModeStarted = false;
java.util.Vector pointModeDots;
java.awt.Point prevPt = null;
JAnnotationImageContainer owner;
boolean htmlSupport = false;
/**
* Default <code>JAnnotationImage</code> constructor
* it set layout manager to <code>null</code>
* and add appropriate mouse listeners
*/
public JAnnotationImage(JAnnotationImageContainer owner){
super();
this.owner = owner;
setLayout(null);
setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
setToolTipText("");
addMouseListener(annotatedImageMouseListener);
addMouseMotionListener(annotatedImageMouseMotionListener);
}
/**
* <code>JAnnotationImage</code> constructor, it creates<br>
* instance from <code>JAnnotationImageModel</code>
* @param model <code>JAnnotationImageModel</code>
* @see JAnnotationImageModel
*/
public JAnnotationImage(JAnnotationImageContainer owner,JAnnotationImageModel model){
this(owner);
setModel(model);
}
/**
* <code>JAnnotationImage</code> constructor, it downloads<br>
* image from <code>resString</code>
* @param resString <code>String</code>
* defines url from where image could be loaded
* it will try to load image from jar file first
*/
public JAnnotationImage(JAnnotationImageContainer owner,String resString){
this(owner);
model = new JAnnotationImageModel();
setImageResourceString(resString);
}
/**
* <code>JAnnotationImage</code> constructor, it creates<br>
* image from <code>bim</code>
* @param bim <code>java.awt.image.BufferedImage</code>
* @see JAnnotationImageContainer#JAnnotationImageContainer(java.awt.image.BufferedImage,String)
*/
public JAnnotationImage(JAnnotationImageContainer owner,java.awt.image.BufferedImage bim){
this(owner);
model = new JAnnotationImageModel(bim);
}
/**
* Returns the preferred size of this container.
* @return an instance of <code>Dimension</code> that represents
* the preferred size of this container.<br>
* if instance of the isn't <code>null</code> it equals to size of the image
* @see Component#getPreferredSize
*/
public Dimension getPreferredSize(){
if(model != null){
java.awt.image.BufferedImage bim = model.getMainImage();
if(bim != null){
return new Dimension(bim.getWidth(),bim.getHeight());
}
}
return new Dimension(20,20);
}
/**
* Returns instance of the <code>JAnnotationImageModel</code>
* @return an instance of the <code>JAnnotationImageModel</code>
* <code>JAnnotationImageModel</code> is accessor to many <code>JAnnotationImage</code><br>
* properties
* @see JAnnotationImageModel
* @see #setModel(JAnnotationImageModel)
*/
public JAnnotationImageModel getModel(){return model;}
/**
* set <code>JAnnotationImageModel</code> for <code>JAnnotationImage</code>
* @param model <code>JAnnotationImageModel</code>
* @see JAnnotationImageModel
* @see #getModel()
*/
public void setModel(JAnnotationImageModel model){
if(this.model == model) return;
if(this.model != null) this.model.clearAnnotationSpots();
this.model = model;
}
/**
* set editing mode for the <code>JAnnotationImage</code>
* @param editMode <code>boolean</code>
* @see #isEditMode()
*/
public void setEditMode(boolean editMode){
if(model != null) model.setEditMode(editMode);
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
java.awt.Component c = javax.swing.SwingUtilities.getWindowAncestor(JAnnotationImage.this);
if(c != null) c.setCursor(java.awt.Cursor.getDefaultCursor());
defaultCursor = AnnotationSpot.SPOT_REGION_UNKNOWN;
}
});
repaint();
}
/**
* Returns current editing mode of the <code>JAnnotationImage</code>
* @return current editing mode<br>
* if editing mode is <code>false</code> editing isn't allowed
* @see #setEditMode(boolean)
*/
public boolean isEditMode(){return (model != null)?model.isEditMode():false;}
public int getChoosingMode(){return (model != null)?model.getChoosingMode():JAnnotationImageModel.CHOOSING_MODE_RECTANGLE;}
public synchronized void setChoosingMode(int choosingMode){
if(model != null) model.setChoosingMode(choosingMode);
}
public boolean getHtmlSupport(){
return htmlSupport;
}
public void setHtmlSupport(boolean htmlSupport){
this.htmlSupport = htmlSupport;
}
public LinkedList getAnnotationSpots(){return (model != null)?model.getAnnotationSpots():null;}
public boolean isAnnotationSpotPopupVisible(){
return (model != null)?model.isAnnotationSpotPopupVisible():false;
}
public javax.swing.JToolTip createToolTip(){
return new JStyledToolTip();
}
public String getToolTipText(java.awt.event.MouseEvent event){
return (model != null)?model.getToolTipText(event):null;
}
public void deleteSelectedSpot(){
if(model != null) model.deleteSelectedSpot();
repaint();
}
public void clearAnnotationSpots(){
if(model != null) model.clearAnnotationSpots();
repaint();
}
public void setToolTipMode(boolean toolTipMode){
if(model != null) model.setToolTipMode(toolTipMode);
}
public boolean isToolTipMode(){
if(model != null) return model.isToolTipMode();
return true;
}
public String toString(){
StringBuffer sb = new StringBuffer();
String eol = "\n";
sb.append("<class>"+getClass().getName()+"</class>"+eol);
//put here usual JComponent stuff
return sb.toString();
}
public AnnotationSpot getSelectedAnnotationSpot(){
return (model != null)?model.getSelectedAnnotationSpot():null;
}
public void dispose(){
removeMouseListener(annotatedImageMouseListener);
removeMouseMotionListener(annotatedImageMouseMotionListener);
if(model != null) model.dispose();
}
//non public methods
protected void setImageResourceString(String imageResourceString){
if(model != null) model.setImageResourceString(imageResourceString);
repaint();
}
protected String getImageResourceString(){return (model != null)?model.getImageResourceString():null;}
ParentComponentTransformer getDraggableComponentTransformer(){return draggableComponentTransformer;}
void setDraggableComponentTransformer(ParentComponentTransformer draggableComponentTransformer){
this.draggableComponentTransformer = draggableComponentTransformer;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
internalPaintComponent(g);
}
protected void internalPaintComponent(Graphics g){
if(model == null) return;
java.awt.image.BufferedImage bim = (isEditMode())?model.getMainEditImage():model.getMainImage();
java.awt.image.BufferedImage backgroundImage = model.getBackgroundImageImage();
if(bim == null || backgroundImage == null) return;
Graphics2D g2d = (Graphics2D)g;
Graphics2D gi2d = backgroundImage.createGraphics();
setImageClip(gi2d);
gi2d.drawImage(bim,null,0,0);
drawAnnotationSpots(gi2d);
gi2d.dispose();
g2d.drawImage(backgroundImage,null,0,0);
}
protected void setImageClip(Graphics g){
g.setClip(getImageClip());
}
protected java.awt.Shape getImageClip(){
java.awt.Insets insets = getInsets();
if(insets == null) insets = new java.awt.Insets(0,0,0,0);
java.awt.geom.Area clipTobe = new java.awt.geom.Area(new Rectangle(insets.left,insets.top,getSize().width - insets.left - insets.right,getSize().height - insets.top - insets.bottom));
java.awt.geom.Area toolTipArea = (model != null)?model.getToolTipAreaForClip(this):null;
if(toolTipArea != null) clipTobe.subtract(toolTipArea);
return clipTobe;
}
protected void drawAnnotationSpots(Graphics2D g2d){
if(model == null) return;
LinkedList annotationSpots = model.getAnnotationSpots();
if(annotationSpots != null){
ListIterator it = annotationSpots.listIterator();
while(it.hasNext()){
AnnotationSpot as = (AnnotationSpot)it.next();
drawAnnotationSpot(g2d,as);
}
}
if(pointsModeStarted && pointModeDots != null && pointModeDots.size() > 0){
Graphics2D gcopy = (Graphics2D)g2d.create();
gcopy.setColor(Color.gray);
gcopy.setStroke(bs);
for(int i = 0; i < pointModeDots.size(); i++){
java.awt.Point pt = (java.awt.Point)pointModeDots.elementAt(i);
if(i > 0){
java.awt.Point ppt = (java.awt.Point)pointModeDots.elementAt(i-1);
gcopy.drawLine(ppt.x,ppt.y,pt.x,pt.y);
}
gcopy.fillRect(pt.x-2,pt.y-2,5,5);
}
gcopy.dispose();
}
}
protected void drawAnnotationSpot(Graphics2D g2d,AnnotationSpot as){
if(as == null || model == null || g2d == null) return;
java.awt.image.BufferedImage bim = model.getMainImage();
if(bim == null) return;
Rectangle r = as.getBounds();
int cropW = r.width;
int cropH = r.height;
Object oldHint = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
if(cropW > 0 && cropH > 0){
java.awt.image.CropImageFilter cif = new java.awt.image.CropImageFilter(r.x,r.y,cropW,cropH);
java.awt.image.ImageProducer producer = new java.awt.image.FilteredImageSource(bim.getSource(),cif);
java.awt.Shape oldClip = g2d.getClip();
if(as.getSpot() != null) g2d.setClip(as.getSpot());
g2d.drawImage(createImage(producer),r.x,r.y,null);
g2d.setClip(oldClip);
java.awt.Stroke oldStroke = g2d.getStroke();
g2d.setStroke(bs);
java.awt.Paint oldPaint = g2d.getPaint();
if(as.getSpotColor() != null){
g2d.setPaint(as.getSpotColor());
}else{
g2d.setPaint(Color.gray);
}
g2d.draw(as.getSpot());
if(oldPaint != null) g2d.setPaint(oldPaint);
g2d.setStroke(oldStroke);
if(isEditMode() && getSelectedAnnotationSpot() == as){
g2d.setColor(Color.red);
g2d.drawRect(r.x,r.y,r.width,r.height);
}
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,oldHint);
}
protected boolean handleDoubleClick(java.awt.event.MouseEvent e){
if(e.getClickCount() == 2){
if(!pointsModeStarted){
// setupPopupMenu();
AnnotationSpot selectedSpot = getSelectedAnnotationSpot();
if(selectedSpot == null || selectedSpot.isEmpty()) return false;
selectedSpot.setupPopupMenu();
return true;
}else{
pointsModeStarted = false;
getNewAnnotationSpot(e.getPoint());
if(owner != null) owner.repaint();
return true;
}
}
return false;
}
DoubleClickThread doubleClickthread = null;
class AnnotatedImageMouseListener extends java.awt.event.MouseAdapter{
public void mousePressed(java.awt.event.MouseEvent e)
{
try{
owner.requestFocusInWindow();
}catch(Throwable t){}
if(model == null || !isEditMode() || isAnnotationSpotPopupVisible()) return;
int modifiers = e.getModifiers();
boolean wasShift = ((modifiers & java.awt.Event.SHIFT_MASK) != 0);
AnnotationSpot currentAnnotationSpot = null;
java.awt.Component source = e.getComponent();
if(draggableComponentTransformer == null){
draggableComponentTransformer = new ParentComponentTransformer();
draggableComponentTransformer.setDestinationComponent(owner);
}
if(draggableImageTransformer == null){
draggableImageTransformer = new ParentComponentTransformer(owner.layeredPane,JAnnotationImage.this);
}
properties.put(START_DRAG_PROPERTY,e.getPoint());//dima from old code so creating without shift is allowed
//dima new code had properties.put(START_DRAG_PROPERTY,e.getPoint()); in the startPressedTimer method
if(!wasShift){
if(getChoosingMode() == JAnnotationImageModel.CHOOSING_MODE_POINTS && (source instanceof JAnnotationImage)){
if(!pointsModeStarted){
if(pointModeDots == null) pointModeDots = new java.util.Vector();
else pointModeDots.removeAllElements();
pointsModeStarted = true;
}else{
return;
}
}else{
pointsModeStarted = false;
if(pointModeDots != null) pointModeDots.removeAllElements();
prevPt = null;
}
model.setSelectedAnnotationSpot(null);
draggableComponentTransformer.setSourceComponent(source);
if(source instanceof JAnnotationImage){
currentDraggable = null;
}else if(source instanceof StaticAnnotationToolTip){
AnnotationSpot spot = ((StaticAnnotationToolTip)source).getOwner();
if(spot == null) return;
currentDraggable = getStaticAnnotationSpotDraggable(spot);
if(currentDraggable == null) return;
}else{
return;
}
}
if(currentDraggable == null || wasShift){
if(!wasShift){
currentAnnotationSpot = model.getAnnotationSpotForPoint(e.getPoint());
model.setSelectedAnnotationSpot(currentAnnotationSpot);
if(currentAnnotationSpot != null) currentDraggable = currentAnnotationSpot;
}else{
startPressedTimer(e.getPoint());
return;
}
}
if(currentDraggable != null){
pointsModeStarted = false;
if(pointModeDots != null) pointModeDots.removeAllElements();
currentDraggable.startDrag(draggableComponentTransformer,e.getPoint());
prevPt = null;
}
}
public void mouseReleased(java.awt.event.MouseEvent e)
{
prevPt = null;
properties.remove(START_DRAG_PROPERTY);
disposePressedTimer();
if(!isEditMode() || model == null) return;
if(pointsModeStarted){
pointModeDots.add(e.getPoint());
}
if(handleDoubleClick(e)) return;
if(currentDraggable != null){
currentDraggable.endDrag(e.getPoint());
currentDraggable = null;
}
if(owner != null) owner.repaint();
}
}
class AnnotatedImageMouseMotionListener extends java.awt.event.MouseMotionAdapter{
public void mouseDragged(java.awt.event.MouseEvent e){
if(pointsModeStarted) return;
//if(currentDraggable == null && pressedTimer != null){dima new source code
// disposePressedTimer();dima new source code
if(currentDraggable == null){//dima from old code
if(pressedTimer != null) disposePressedTimer();//dima from old code
java.awt.Point startDragPoint = (java.awt.Point)properties.get(START_DRAG_PROPERTY);
AnnotationSpot currentAnnotationSpot = getNewAnnotationSpot(startDragPoint);
currentDraggable = currentAnnotationSpot;
if(currentDraggable != null) currentDraggable.startDrag(null,createPointFromPoint2D(startDragPoint));
}
if(currentDraggable != null){
currentDraggable.doDrag(e.getPoint());
Graphics gc = JAnnotationImage.this.getGraphics();
if(gc == null){
repaint();
}else{
//setImageClip(gc); dima why I was need it ?????? it looks like it works much better without that
//internalPaintComponent(gc);
gc.dispose();
}
if(owner != null) owner.repaint();
}
}
public void mouseMoved(java.awt.event.MouseEvent e){
adjustCursor(e.getPoint());
if(getChoosingMode() == JAnnotationImageModel.CHOOSING_MODE_POINTS && (e.getSource() instanceof JAnnotationImage) &&
pointsModeStarted && pointModeDots != null && pointModeDots.size() > 0){
Graphics2D gc = (Graphics2D)getGraphics();
java.awt.Point dpt = (java.awt.Point)pointModeDots.elementAt(pointModeDots.size() - 1);
gc.setXORMode(java.awt.Color.red);
if(prevPt != null){
gc.drawLine(dpt.x,dpt.y,prevPt.x,prevPt.y);
}
prevPt = e.getPoint();
gc.drawLine(dpt.x,dpt.y,prevPt.x,prevPt.y);
gc.dispose();
}
}
}
public Draggable getStaticAnnotationSpotDraggable(AnnotationSpot as){
if(as == null || as.isToolTipMode() || as.getAnnotationToolTip() == null) return null;
Draggable draggable = new JLayeredPaneDraggable(as,as.getAnnotationToolTip());
return draggable;
}
protected AnnotationSpot getNewAnnotationSpot(java.awt.Point pt){
AnnotationSpot newAnnotationSpot = null;
if(pt == null) return newAnnotationSpot;
int px = (int)Math.round(pt.getX());
int py = (int)Math.round(pt.getY());
switch(model.getChoosingMode()){
case JAnnotationImageModel.CHOOSING_MODE_POINTS:
if(pointModeDots == null || pointModeDots.size() < 3) return null;
int []xs = new int[pointModeDots.size()+1];
int []ys = new int[pointModeDots.size()+1];
for(int i = 0; i < pointModeDots.size(); i++){
java.awt.Point dpt = (java.awt.Point)pointModeDots.elementAt(i);
xs[i] = dpt.x;
ys[i] = dpt.y;
}
xs[xs.length - 1] = xs[0];
ys[ys.length - 1] = ys[0];
newAnnotationSpot = new AnnotationSpot(new java.awt.Polygon(xs,ys,xs.length));//
break;
case JAnnotationImageModel.CHOOSING_MODE_POLYGON:
newAnnotationSpot = new AnnotationSpot(new java.awt.Polygon(new int[]{px},new int[]{py},1));//
break;
case JAnnotationImageModel.CHOOSING_MODE_ELLIPSE:
newAnnotationSpot = new AnnotationSpot(new java.awt.geom.Ellipse2D.Double(px,py,0,0));//
break;
default:
newAnnotationSpot = new AnnotationSpot(new Rectangle(px,py,0,0));
break;
}
model.setSelectedAnnotationSpot(newAnnotationSpot);
newAnnotationSpot.setChoosingMode(model.getChoosingMode());
newAnnotationSpot.setEnclosedRectangle(new Rectangle(dragLimit,dragLimit,getSize().width - 2*dragLimit,getSize().height - 2*dragLimit));
java.awt.geom.Point2D aToolLocation = (draggableComponentTransformer != null)?draggableComponentTransformer.transform(pt):pt;
newAnnotationSpot.setAnnotationToolTipLocation(createPointFromPoint2D(aToolLocation));
newAnnotationSpot.setAnnotation(TEST_TOOL_TIP);
newAnnotationSpot.setAnnotationImage(this);
model.addAnnotationSpot(newAnnotationSpot,true);
java.awt.Container container = owner.layeredPane;
if(container instanceof javax.swing.JLayeredPane){
newAnnotationSpot.createAnnotationToolTip();
int layerIndex = javax.swing.JLayeredPane.DRAG_LAYER.intValue();
javax.swing.JComponent jc = newAnnotationSpot.getAnnotationToolTip();
if(jc != null){
((javax.swing.JLayeredPane)container).add(jc,new Integer(layerIndex+newAnnotationSpot.getIndex()));
jc.addMouseListener(annotatedImageMouseListener);
jc.addMouseMotionListener(annotatedImageMouseMotionListener);
newAnnotationSpot.checkAnnotationToolTipPosition();
}
}
return newAnnotationSpot;
}
protected void checkAnnotationToolTips(){
if(model == null) return;
java.awt.Container container = getParent();
if(container instanceof javax.swing.JLayeredPane){
LinkedList annotationSpots = model.getAnnotationSpots();
if(annotationSpots != null){
int layerIndex = javax.swing.JLayeredPane.DRAG_LAYER.intValue();
ListIterator it = annotationSpots.listIterator();
while(it.hasNext()){
AnnotationSpot as = (AnnotationSpot)it.next();
javax.swing.JComponent jc = as.getAnnotationToolTip();
if(jc == null || container.isAncestorOf(jc)) continue;
as.checkAnnotationToolTip();
((javax.swing.JLayeredPane)container).add(jc,new Integer(layerIndex+as.getIndex()));
jc.removeMouseListener(annotatedImageMouseListener);//just in case
jc.removeMouseMotionListener(annotatedImageMouseMotionListener);//just in case
jc.addMouseListener(annotatedImageMouseListener);
jc.addMouseMotionListener(annotatedImageMouseMotionListener);
}
}
}
}
protected void startPressedTimer(java.awt.Point pt){
//properties.put(START_DRAG_PROPERTY,pt);dima new source code
//old code diesn't have that line here so creating without shift is allowed
disposePressedTimer();
final java.awt.Point startPoint = createPointFromPoint2D(pt);
pressedTimer = new javax.swing.Timer(1000,new java.awt.event.ActionListener(){
public void actionPerformed(java.awt.event.ActionEvent evt){
disposePressedTimer();
currentDraggable = new JLayeredPaneDraggable(JAnnotationImage.this);
currentDraggable.startDrag(draggableImageTransformer,(java.awt.Point)properties.get(START_DRAG_PROPERTY));
}
});
pressedTimer.start();
}
protected void disposePressedTimer(){
if(pressedTimer != null){
if(pressedTimer.isRunning()) pressedTimer.stop();
pressedTimer = null;
}
}
javax.swing.Timer pressedTimer;
protected void adjustCursor(java.awt.Point pt){
if(model == null) return;
java.awt.Window w = javax.swing.SwingUtilities.getWindowAncestor(this);
if(!(w instanceof java.awt.Frame)) return;
final java.awt.Frame frame = (java.awt.Frame)w;
int cursorSpotRegion = model.getCursorSpotRegionForPoint(pt);
final int runnableCursorSpotRegion = cursorSpotRegion;
if((cursorSpotRegion == AnnotationSpot.SPOT_REGION_ALL) && (defaultCursor != cursorSpotRegion)){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
frame.setCursor(java.awt.Cursor.getPredefinedCursor(isEditMode()?java.awt.Cursor.HAND_CURSOR:java.awt.Cursor.CROSSHAIR_CURSOR));
defaultCursor = runnableCursorSpotRegion;
}
});
}
if((cursorSpotRegion == AnnotationSpot.SPOT_REGION_UNKNOWN || cursorSpotRegion == AnnotationSpot.SPOT_REGION_DEFINE) && (defaultCursor != cursorSpotRegion)){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
frame.setCursor(java.awt.Cursor.getDefaultCursor());
defaultCursor = runnableCursorSpotRegion;
}
});
}
if(cursorSpotRegion >= AnnotationSpot.SPOT_REGION_TOP_LEFT && cursorSpotRegion <= AnnotationSpot.SPOT_REGION_BOTTOM && (defaultCursor != cursorSpotRegion)){
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
int cursorType = java.awt.Cursor.HAND_CURSOR;
switch(runnableCursorSpotRegion){
case AnnotationSpot.SPOT_REGION_TOP_LEFT: cursorType = java.awt.Cursor.NW_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_TOP_RIGHT: cursorType = java.awt.Cursor.NE_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_BOTTOM_LEFT: cursorType = java.awt.Cursor.SW_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_BOTTOM_RIGHT: cursorType = java.awt.Cursor.SE_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_LEFT: cursorType = java.awt.Cursor.W_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_RIGHT: cursorType = java.awt.Cursor.E_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_TOP: cursorType = java.awt.Cursor.N_RESIZE_CURSOR; break;
case AnnotationSpot.SPOT_REGION_BOTTOM: cursorType = java.awt.Cursor.S_RESIZE_CURSOR; break;
}
frame.setCursor(java.awt.Cursor.getPredefinedCursor(cursorType));
defaultCursor = runnableCursorSpotRegion;
}
});
}
}
protected int defaultCursor = 1;
static java.awt.Point createPointFromPoint2D(java.awt.geom.Point2D p2d){
if(p2d == null) return null;
return new java.awt.Point((int)Math.round(p2d.getX()),(int)Math.round(p2d.getY()));
}
//final static String TEST_TOOL_TIP = "<font color=\"#FF0000\">xxxxxxxxx<font color=\"#00FF00\">zzzzz dsfsdfsd sdfsdfdsfsdf <br>sdfsdfsdfsd sdfsdfdsf sdfdsfdsf fsdfsd </font>yyyyy</font>";
final static String TEST_TOOL_TIP = "Annotation";
java.awt.BasicStroke bs = new java.awt.BasicStroke(1.25f);
public static class JLayeredPaneDraggable implements Draggable{
java.awt.geom.Point2D startDragPoint;
java.awt.geom.Point2D startParentDragPoint;
java.awt.geom.Point2D startComponentLocation;
java.awt.Component owner;
AnnotationSpot annotationSpot;
CoordinateTransformer currentTransformer;
JLayeredPaneDraggable(java.awt.Component owner){
this(null,owner);
}
JLayeredPaneDraggable(AnnotationSpot annotationSpot,java.awt.Component owner){
this.owner = owner;
this.annotationSpot = annotationSpot;
}
public int startDrag(CoordinateTransformer transformer,java.awt.Point pt){
if(owner == null) return 0;
startComponentLocation =owner.getLocation();
startParentDragPoint = (transformer != null)?transformer.transform(pt):pt;
startDragPoint = pt;
currentTransformer = transformer;
return 0;
}
public void doDrag(java.awt.Point pt){
if(owner == null) return;
java.awt.geom.Point2D currPoint = (currentTransformer != null)?currentTransformer.transform(pt):pt;
int newx = (int)Math.round(startComponentLocation.getX() + (currPoint.getX() - startParentDragPoint.getX()));
int newy = (int)Math.round(startComponentLocation.getY() + (currPoint.getY() - startParentDragPoint.getY()));
if(newx < 0) newx = 0;
if(newy < 0) newy = 0;
if(newx + owner.getSize().width > owner.getParent().getSize().width) newx = owner.getParent().getSize().width - owner.getSize().width;
if(newy + owner.getSize().height > owner.getParent().getSize().height) newy = owner.getParent().getSize().height - owner.getSize().height;
final int newix = newx;
final int newiy = newy;
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run(){
owner.setLocation(newix,newiy);
if(owner.getParent() != null) owner.getParent().repaint();
}
});
}
public void endDrag(java.awt.Point pt){
if(annotationSpot == null || owner == null) return;
annotationSpot.setAnnotationToolTipLocation(owner.getLocation());
}
public void setDraggable(boolean draggable){}
public boolean isDraggable(){return true;}
}
}
class ParentComponentTransformer implements CoordinateTransformer{
java.awt.Component destinationComponent;
java.awt.Component sourceComponent;
ParentComponentTransformer(){
}
ParentComponentTransformer(java.awt.Component destinationComponent,java.awt.Component sourceComponent){
this.destinationComponent = destinationComponent;
this.sourceComponent = sourceComponent;
}
public java.awt.geom.Point2D transform(java.awt.geom.Point2D p2d){
if(destinationComponent == null || sourceComponent == null || p2d == null) return p2d;
java.awt.Point pt = new java.awt.Point((int)Math.round(p2d.getX()),(int)Math.round(p2d.getY()));
return javax.swing.SwingUtilities.convertPoint(sourceComponent,pt,destinationComponent);
}
public void setSourceComponent(java.awt.Component sourceComponent){
this.sourceComponent = sourceComponent;
}
public void setDestinationComponent(java.awt.Component destinationComponent){
this.destinationComponent = destinationComponent;
}
}
class DoubleClickThread extends Thread{
JAnnotationImage owner;
int interval;
boolean doubleClick = false;
DoubleClickThread(JAnnotationImage owner,int interval){
this.owner = owner;
this.interval = interval;
start();
}
public void run(){
try{
sleep(interval);
if(doubleClick) System.out.println("WAS 2 click");
else System.out.println("NO 2 click");
}catch(Throwable t){}
}
public void wasDoubleClick(){
doubleClick = true;
}
}