JFrame drag/move listener?

I'd like to implement a listener to my JFrames to invoke a method

when a window has been moved/dragged. I don't want it to be called

repeatedly while the window is dragged, but rather called a single

time after the mouse button is released and the new position is set.

My searching has yielded listeners for when it's closed or minimized...

but I can't seem to locate what I'm looking for. Can someone please share

what class and method(s) I'm looking for?

Thanks!

[523 byte] By [zredbarona] at [2007-10-3 4:19:59]
# 1
ComponentListener's componentMoved()
Michael_Dunna at 2007-7-14 22:21:53 > top of Java-index,Desktop,Core GUI APIs...
# 2

thanks, but componentMoved() is called repeatedly while the window

is being dragged.

i tried using MouseAdapter's mouseReleased(), but it doesn't seem

to be attached to the JFrame's title bar.

any other ideas? again, i only want the event to be triggered when the

mouse is released (the JFrame is done moving).

thanks again.

zredbarona at 2007-7-14 22:21:53 > top of Java-index,Desktop,Core GUI APIs...
# 3

works OK on 1.4.0_01, only prints the coords after move completed

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

class Testing extends JFrame

{

public Testing()

{

setSize(100,100);

setLocation(300,100);

setDefaultCloseOperation(EXIT_ON_CLOSE);

addComponentListener(new ComponentAdapter(){

public void componentMoved(ComponentEvent ce){

System.out.println("x = "+getX()+", y = "+getY());

}

});

}

public static void main(String[] args) {new Testing().setVisible(true);}

}

Michael_Dunna at 2007-7-14 22:21:53 > top of Java-index,Desktop,Core GUI APIs...
# 4

> works OK on 1.4.0_01, only prints the coords after move completed

On XP using 1.4.2_06 the componentMoved event fires continously.

One workaround, although not 100% what you want, is to use a Timer. The componentMoved event will keep restarting the Timer so it doesn't fire for "x" ms after the component has stopped moving. Not the same as using mouseReleased, but close.

camickra at 2007-7-14 22:21:53 > top of Java-index,Desktop,Core GUI APIs...
# 5

yeah, on 1.5.0_07 it outputs very fast during movement...

x = 304, y = 103

x = 307, y = 104

x = 311, y = 110

x = 311, y = 110

x = 316, y = 113

x = 318, y = 116

x = 323, y = 119

x = 324, y = 120

x = 328, y = 122

x = 331, y = 125

x = 335, y = 128

x = 338, y = 130

x = 341, y = 131

x = 345, y = 132

x = 348, y = 134

zredbarona at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 6

it *would* work, but i'd rather not do the timer.

oddly, attaching a mouse event to the jframe fires if you click on the

border of the jframe, but not if you click on the title bar. is the title bar

a different kind of component or something? one that should have

its own, separate listener?

another idea is if there was a global mouse listener that knew if the

mouse was clicking regardless of components. if i had that i could

link the componentMoved() to that and come up with a solution that

way. is there such a thing?

thanks again.

zredbarona at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 7
> another idea is if there was a global mouse listener > is there such a thing?Yes. You use an AWTEventListener to listen for all generated events.However, I already tested it and it still doesn't work.
camickra at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 8

thanks for the heads-up on it not working on versions > what I'm using

try this (untested)

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

class Testing extends JFrame

{

boolean moved = false;

public Testing()

{

setSize(200,100);

setLocation(300,100);

setDefaultCloseOperation(EXIT_ON_CLOSE);

addMouseListener(new MouseAdapter(){

public void mouseReleased(MouseEvent me){

if(moved == true) System.out.println("x = "+getX()+", y = "+getY());

moved = false;

}

});

addComponentListener(new ComponentAdapter(){

public void componentMoved(ComponentEvent ce){

moved = true;

}

});

}

public static void main(String[] args)

{

JFrame.setDefaultLookAndFeelDecorated(true);//<--note this change for mouseListener

new Testing().setVisible(true);

}

}

Michael_Dunna at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 9

it never gets to the mouse released part from clicks on the jframe's title

bar, which doesnt make sense to me. it only reaches that if you click on

the border, such as an attempt to resize...

(possibly interior as well...untested, but i need the title bar to listen)

[gotta run...will follow up tomorrow. many thanks]

zredbarona at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 10
> try this (untested)Works fine in 1.4.2_06.
camickra at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 11
> it never gets to the mouse released part from clicks on the jframe's title might be another thing broken between versionsI'd upgrade, but later versions just crash this box(hmm... if I accidentally drop a sledge hammer, I might get a new PC)
Michael_Dunna at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 12
> Works fine in 1.4.2_06.thanks - I'll put the sledge hammer away (for the moment)
Michael_Dunna at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 13
the code above does work as is in 1.5.0, but I don't use JFrame.setDefaultLookAndFeelDecorated(true);in my project and I'm using another L&F entirely. Any other options?
zredbarona at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 14

probably the timer that was suggested earlier is your only other option.

try this (again untested, as my componentMoved doesn't fire continuously)

I've set it for 150ms, so this needs a lot of testing

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

class Testing extends JFrame

{

boolean timerStarted = false;

int oldX, oldY;

javax.swing.Timer timer;

public Testing()

{

setSize(100,100);

setLocation(300,100);

setDefaultCloseOperation(EXIT_ON_CLOSE);

ActionListener al = new ActionListener(){

public void actionPerformed(ActionEvent ae){

if(getX() == oldX && getY() == oldY)

{

System.out.println("x = "+getX()+", y = "+getY());

timer.stop();

timerStarted = false;

}

else

{

oldX = getX();

oldY = getY();

}

}

};

timer = new javax.swing.Timer(150,al);

addComponentListener(new ComponentAdapter(){

public void componentMoved(ComponentEvent ce){

if(timerStarted == false)

{

timerStarted = true;

timer.start();

}

}

});

setVisible(true);

oldX = getX();

oldY = getY();

}

public static void main(String[] args) {new Testing();}

}

Michael_Dunna at 2007-7-14 22:21:54 > top of Java-index,Desktop,Core GUI APIs...
# 15

Thanks for the timer code.

I ended up finding a working solution. I was previously attempting to

add the mouse listener to the JFrame itself, what I needed to do was:

LFRootPaneUI rootPaneUI = (LFRootPaneUI) frame.getRootPane().getUI();

rootPaneUI.getTitlePane().addMouseListener(new FrameListener(C));

// where LFRootPaneUI is a class created in the LookAndFeel project

// I've imported. I assume an equivalent would be needed if I wanted to use

// UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

Thanks again for all of the efforts in this thread.

zredbarona at 2007-7-21 10:28:18 > top of Java-index,Desktop,Core GUI APIs...