I've got a problem when trying to drag a JPanel. If I implement it purely in MouseDragged as:
public void mouseDragged(MouseEvent me) {
me.getSource().setLocation(me.getX(), me.getY());
}
I get a weird effect of the moved object bouncing between two positions all the time (generating more "dragged" events). If I do it in the way described in this post, but with:
public void mouseDragged(MouseEvent me) {
if (draggedElement == null)
return;
me.translatePoint(this.draggedXAdjust, this.draggedYAdjust);
draggedElement.setLocation(me.getX(), me.getY());
}
I get an effect of the element bouncing a lot less, but it's still visible and the element moves only ½ of the way the mouse pointer does. Why does this happen / how can I fix this situation?
OK. Old question but if anyone comes across this like I did this can be solved relatively simply. For dragging a JPanel in a JFrame I did:
#Override
public void mousePressed(MouseEvent e) {
if (panel.contains(e.getPoint())) {
dX = e.getLocationOnScreen().x - panel.getX();
dY = e.getLocationOnScreen().y - panel.getY();
panel.setDraggable(true);
}
}
#Override
public void mouseDragged(MouseEvent e) {
if (panel.isDraggable()) {
panel.setLocation(e.getLocationOnScreen().x - dX, e.getLocationOnScreen().y - dY);
dX = e.getLocationOnScreen().x - panel.getX();
dY = e.getLocationOnScreen().y - panel.getY();
}
}
The key is to use .getLocationOnScreen() and update the adjustment at the end of each call of mouseDragged.
Try this
final Component t = e.getComponent();
e.translatePoint(getLocation().x + t.getLocation().x - px, getLocation().y + t.getLocation().y - py);
and add this method:
#Override
public void mousePressed(final MouseEvent e) {
e.translatePoint(e.getComponent().getLocation().x, e.getComponent().getLocation().y);
px = e.getX();
py = e.getY();
}
I don't know if you can just do it using a mouseDragged event. In the past I use mousePressed to save the original point and mouse dragged to get the current point. In both cases I translate the points to the location on the screen. Then the difference between the two points is easily calculated and the location can be set appropriately.
My general purpose class for this is the Component Mover class.
Related
I am working on a swing application which run on a touch screen linux tablet. I want to implement a module in which i find that in which direction user swipe its finger on the screen. I am using MouseMotionListener to find the position of the mouse. But confusing now that how i can find the exact direction of the mouse movement. I only interested to find upward and downward movement on jframe. Can someone give me idea about that
I am using MouseMotionListener to find the position of the mouse.
I would guess you need to keep track of two MouseEvents:
the previous event (or maybe the mousePressed event which started the swipe?)
the current event.
so that you have access to the two points generated by each event.
Then you compare the two points using basic math. If the current y value is greater you are swiping down, otherwise up.
I wanted to add this example code illustrating #camickr's answer since it might help - as it got rejected as an edit, and I don't have enough points to add comments, here it is:
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class DragDirectionDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame("Drag Direction Demo");
frame.setSize(500, 500);
frame.setVisible(true);
frame.addMouseListener(new MouseListener() {
float lastY = 0;
public void mouseReleased(MouseEvent e) {
System.out.println("Mouse released at " + e.getY());
if (e.getY() < lastY) {
System.out.println("Upward swipe");
} else if (e.getY() > lastY) {
System.out.println("Downward swipe");
} else {
System.out.println("No movement");
}
;
}
public void mousePressed(MouseEvent e) {
System.out.println("Mouse clicked at " + e.getY());
lastY = e.getY();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
}
});
}
}
It is just a toy example illustrating the approach explained in #camickr's answer: tracking the y coordinate when the motion starts (the mouse button being depressed, in my example); then, comparing it to the y coordinate when the motion finishes (mouse button released, in my example - may need tweaking for touch, I don't know).
Observe the console output indicating what the motion has been picked up as. Good luck!
I have a code for dragging a label width mouse.
lbl_banner.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e) {
//catching the current values for x,y coordinates on screen
x_pressed = e.getX();
y_pressed = e.getY();
}
});
lbl_banner.addMouseMotionListener(new MouseMotionAdapter(){
#Override
public void mouseDragged(MouseEvent e){
//and when the Jlabel is dragged
setLocation(e.getXOnScreen() - x_pressed, e.getYOnScreen() - y_pressed);
}
});
Now, how do I make a function: While I'm dragging this label around the Screen, If the Label by dragging touches other object (label, button,...) to do something.
if(//labelTouchesSomething){//do something}
While this is not technically a dragging but the dynamic move of a component (dragging is the transfer of contents in between components), you can compute the intersection of the current moving component against other components (this may need some navigation inside your hierarchy). May be this can help you: How do I detect the collison of components?. You can also use the methods contains of Component to determine if some coordinates are inside a component or not.
In my animation one of elements is moving oval. There are two ways to control it. The first is setting x,y position by mouse listener and the second is Key Listener. During first using animation both methods work. But after using stop (clear) button mouse listener doesn't work, but Key method is still working.
Code stop method:
void clear() {
waves.clear();
xz_list.clear();
yz_list.clear();
time_list.clear();
f_list.clear();
time=0;
timer.stop();
repaint();
}
MouseListener method:
void SourcePosition(double v, String d) {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
{
x_o = e.getX();
y_o = e.getY();
repaint();
}
}
});
}
Generally this is application showing Doppler Effect. Start button make setting data from interface, disable interface and start animation and chart. Stop button uses clear() method and enable interface.
I have a filled circle drawn on a canvas and I'm trying to get it to move based on a click and drag method with the mouse. I've managed to checked whether the mouse pointer is within the bounds of the circle, and when I drag the mouse, the variable storing the position of the circle updates as it should, but the circle itself is not redrawing as I'm dragging (the most it will do is flicker). My problem is at the end where I'm overriding mouseDragged().
getCanvas().addMouseListener(new MouseAdapter()
{
#Override
public void mouseClicked(MouseEvent event)
{
super.mouseClicked(event);
Point mousePosition = event.getPoint();
if (_circle.getShape1().contains(mousePosition))
Main.debugLabel.setText("Clicked");
}
#Override
public void mouseReleased(MouseEvent event)
{
super.mouseReleased(event);
_circle.isDraggable = false;
Main.debugLabel.setText("Released");
}
#Override
public void mousePressed(MouseEvent event)
{
super.mousePressed(event);
int button = event.getModifiers();
if (button == InputEvent.BUTTON1_MASK)
{
_circle.isDraggable = true;
Main.debugLabel.setText("Pressed");
}
}
});
getCanvas().addMouseMotionListener(new MouseAdapter()
{
#Override
public void mouseDragged(MouseEvent event)
{
super.mouseDragged(event);
Point mousePosition = event.getPoint();
if (_circle.isDraggable)
{
_circle.posX = mousePosition.x;
_circle.posY = mousePosition.y;
Main.debugLabel.setText("Dragging " + _circle.posX);
getCanvas().repaint();
}
}
#Override
public void mouseMoved(MouseEvent event)
{
super.mouseMoved(event);
Point mousePosition = event.getPoint();
if (_circle.getShape1().contains(mousePosition))
Main.debugLabel.setText("Within Bounds");
else if (!_circle.getShape1().contains(mousePosition) && !_circle.isDraggable)
Main.debugLabel.setText("Out of Bounds");
}
});
As shown in this example, one approach is to maintain two Point instances. One holds the last mouse location; the other holds the desired target location; both are in in component-relative coordinates.
In mousePressed(),
Initialize the last mouse location.
Optionally, mark the target as selected.
Invoke repaint() to display the selected appearance.
In mouseDragged(),
Update the target location by the difference between the new and old mouse locations.
Update the last mouse location to the current mouse location.
Invoke repaint().
I have a vector (_storedShapes) to store the painted rectangles (_rect). I also plan on adding ellipses. What I am trying to do is add a shape to the spot on the screen that I click and be able to resize it. Here is a website with a demo of what I am trying to do http://code.google.com/p/tangram-canvas/downloads/detail?name=TangramCanvas-1.2.zip.
The only difference from this demo is that I want my shape to expand on all sides from its center as I drag it.
From my code right now, a pre-sized rectangle pops up on the canvas where I click and then when I drag, just follows the cursor on the screen.
private class DrawSListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
_preX = (int) (_rect.getX() - e.getX());
_preY = (int) (_rect.getY() - e.getY());
DrawingPanel dp = new DrawingPanel();
_rect = new SketchyRectangle(dp);
System.out.println("new rec");
// if (_rect.contains(e.getPoint())) {
_rect.setLocation(e.getX(), e.getY());
System.out.println("setLocation");
repaint();
System.out.println("paint");
//}
}
}
/**
* Private class DrawListener is called when the DrawEllipse or DrawRectangle radio buttons are selected.
*
*/
private class DrawListener implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
if (_rect.contains(e.getPoint())) {
_rect.setLocation(_preX, _preY);
_storedShapes.add(_rect);
repaint();
}
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
}
I would keep two coordinates in the object (or wherever makes sense): prevDragCoord, shapeCenter. On mouse click store the coordinate of the event in both members. On mouse drag, update the rectangle size by adding to it the difference of the current event coordinate minus the coordinate stored in the object. Set the rectangle's location by setting the difference between the shapeCenter member and the rectangle size divided by 2 (e.g. shapeCenter.x - rect.xLength/2). Store the current coordinate in the object's coordinate member so it's ready to update on any subsequent calls to your handler.
I'll leave the implementation up to you. Maybe you can do it with only one variable, or maybe no variables because the event object has some sort of awesome data in it to get this done. This should be the general idea anyway.