001 /* 002 * Copyright (c) 2005, romain guy (romain.guy@jext.org) and craig wickesser (craig@codecraig.com) 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 006 * 007 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 008 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 009 * * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 010 * 011 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 012 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 013 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 014 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 015 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 016 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 017 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 018 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 019 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 020 * POSSIBILITY OF SUCH DAMAGE. 021 */ 022 023 package net.java.swingfx.jdraggable; 024 025 import java.awt.Component; 026 import java.awt.Container; 027 import java.awt.Point; 028 import java.awt.Rectangle; 029 import java.awt.event.MouseEvent; 030 031 import javax.swing.SwingUtilities; 032 import javax.swing.event.MouseInputAdapter; 033 034 /** 035 * A listener which receives {@link java.awt.event.MouseEvent}'s to aid 036 * in the "dragging" of a {@link java.awt.Component} 037 * 038 * @author craig 039 * @since v0.1 040 * <br> 041 * $Header: /cvs/swingfx/docs/api/src-html/net/java/swingfx/jdraggable/DraggableListener.html,v 1.1 2005/06/23 00:24:44 codecraig Exp $ 042 */ 043 public class DraggableListener extends MouseInputAdapter { 044 private Point componentTopLeft; 045 private Point componentTopRight; 046 private Point componentBottomLeft; 047 private Point componentBottomRight; 048 private Point containerTopLeft; 049 private Point containerTopRight; 050 private Point containerBottomLeft; 051 private Point containerBottomRight; 052 053 private DraggableManager dragManager; 054 private Component draggableComponent; 055 private Container draggableContainer; 056 private int offsetX; 057 private int offsetY; 058 059 /** 060 * Creates a new listener which communicates with the given {@link DraggableManager} 061 * during "dragging" 062 * 063 * @param dragManager the <code>DraggableManager</code> to communicate with 064 */ 065 public DraggableListener(DraggableManager dragManager) { 066 this.dragManager = dragManager; 067 this.draggableContainer = dragManager.getDraggableContainer(); 068 } 069 070 /** 071 * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent) 072 */ 073 public void mouseDragged(MouseEvent e) { 074 if (dragManager.dragging()) { 075 //TODO: come up with a better solution than this, and once we do, remove 076 // shouldNullifyLayout() from the interface 077 if (dragManager.shouldNullifyLayout() && draggableContainer.getLayout() != null) { 078 draggableContainer.setLayout(null); 079 } 080 int x = e.getX(); 081 int y = e.getY(); 082 Point pt = SwingUtilities.convertPoint(draggableComponent, x, y, draggableContainer); 083 draggableComponent.setLocation(pt.x - offsetX, pt.y - offsetY); 084 stayInContainer(); 085 } 086 } 087 088 /** 089 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) 090 */ 091 public void mousePressed(MouseEvent e) { 092 draggableComponent = e.getComponent(); 093 if (dragManager.startDrag(draggableComponent)) { 094 offsetX = e.getX(); 095 offsetY = e.getY(); 096 } 097 } 098 099 /** 100 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) 101 */ 102 public void mouseReleased(MouseEvent e) { 103 dragManager.stopDrag(); 104 draggableComponent = null; 105 } 106 107 /** 108 * Determines if the current "draggable component" is in the 109 * "draggable container" 110 * 111 * @return <code>true</code> if the component is in the container, 112 * <code>false</code> otherwise 113 */ 114 private boolean isInContainer() { 115 Rectangle r = new Rectangle( draggableContainer.getWidth(), draggableContainer.getHeight() ); 116 int wC = (int)r.getWidth(); 117 int hC = (int)r.getHeight(); 118 containerTopLeft = r.getLocation(); 119 containerTopRight = new Point( (int)containerTopLeft.getX()+wC, (int)containerTopLeft.getY() ); 120 containerBottomLeft = new Point( (int)containerTopLeft.getX(), (int)containerTopLeft.getY()+hC ); 121 containerBottomRight = new Point( (int)containerTopLeft.getX()+wC, (int)containerTopLeft.getY()+hC ); 122 int w = draggableComponent.getWidth(); 123 int h = draggableComponent.getHeight(); 124 componentTopLeft = draggableComponent.getLocation(); 125 componentTopRight = new Point( (int)componentTopLeft.getX()+w, (int)componentTopLeft.getY() ); 126 componentBottomLeft = new Point( (int)componentTopLeft.getX(), (int)componentTopLeft.getY()+h ); 127 componentBottomRight = new Point( (int)componentTopLeft.getX()+w, (int)componentTopLeft.getY()+h ); 128 if( !r.contains(componentTopLeft) ) return false; 129 if( !r.contains(componentTopRight) ) return false; 130 if( !r.contains(componentBottomLeft) ) return false; 131 if( !r.contains(componentBottomRight) ) return false; 132 return true; 133 } 134 135 /** 136 * Assures that the "draggable component" stays within the "draggable container" 137 */ 138 private void stayInContainer(){ 139 /* if the plate goes is too far in right-direction, shift it back*/ 140 if( !isInContainer() ){ 141 double x = componentTopRight.getX(); 142 double xC = containerTopRight.getX(); 143 if( x > xC ){ 144 draggableComponent.setLocation( (int)(componentTopLeft.getX()+xC-x), (int)componentTopLeft.getY()); 145 } 146 } 147 /* if the plate goes is too far in left-direction, shift it back */ 148 if( !isInContainer() ){ 149 double x = componentTopLeft.getX(); 150 double xC = containerTopLeft.getX(); 151 if( x < xC ){ 152 draggableComponent.setLocation( (int)(componentTopLeft.getX()+xC-x), (int)componentTopLeft.getY()); 153 } 154 } 155 /* if the plate goes is too far in top-direction, shift it back */ 156 if( !isInContainer() ){ 157 double y = componentTopLeft.getY(); 158 double yC = containerTopLeft.getY(); 159 if( y < yC ){ 160 draggableComponent.setLocation( (int)componentTopLeft.getX(), (int)(componentTopLeft.getY()+yC-y)); 161 } 162 } 163 /* if the plate goes is too far in bottom-direction, shift it back */ 164 if( !isInContainer() ){ 165 double y = componentBottomLeft.getY(); 166 double yC = containerBottomLeft.getY(); 167 if( y > yC ){ 168 draggableComponent.setLocation( (int)componentTopLeft.getX(), (int)( componentTopLeft.getY()+yC-y) ); 169 } 170 } 171 } 172 }