Reputation: 757
I'm working on making a undecorated JFrame
, so I need a way to change the window position. So far, I can make the window follow the mouse, but I can't make it stop. I added an ActionPerformed
to a JButton
:
test = true;
while (test) {
setLocation(MouseInfo.getPointerInfo().getLocation().x - 20, MouseInfo.getPointerInfo().getLocation().y - 20);
}
The offsets are there to keep the pointer inside the JButton
, which graphically looks pressed during the while
. It works wonders, very fast. But I don't know how to make it stop. I tried to add a MouseClicked
that sets test
to false, but it didn't worked. Apparently, no Listener works while the loop is running.
Is there a way to know if the mouse was clicked inside of that while
? So, without a Listener or Event? Or is there another approach to re-position the window?
Edit:
Thanks again to Jurgen Camilleri, but I'd like to add a modified version of his example, which I believe is simpler, containing the barely necessary stuff to make this work.
package testbench;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class DraggableFrame
extends JFrame
implements MouseListener, MouseMotionListener {
static Point dragged = null;
static Point pressed = null;
public DraggableFrame () throws HeadlessException {
addMouseListener(this);
addMouseMotionListener(this);
setBounds(0, 0, 320, 240);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setUndecorated(true);
}
public static void main (String args[]) {
EventQueue.invokeLater(new Runnable () {
@Override
public void run () {
new DraggableFrame().setVisible(true);
}
});
}
@Override
public void mouseClicked (MouseEvent e) {}
@Override
public void mouseDragged (MouseEvent e) {
dragged = e.getLocationOnScreen();
setLocation(
(int)(dragged.getX() - pressed.getX()),
(int)(dragged.getY() - pressed.getY()));
}
@Override
public void mouseEntered (MouseEvent e) {}
@Override
public void mouseExited (MouseEvent e) {}
@Override
public void mouseMoved (MouseEvent e) {}
@Override
public void mousePressed (MouseEvent e) {
pressed = e.getPoint();
}
@Override
public void mouseReleased (MouseEvent e) {}
}
Don't mind the empty overridden methods, they are necessary. In the actual program I was developing, I used a separate class for the listeners, which works just as well. Also, it seems to not matter whether you implement a Listener or extend an Adapter. On one side, you can implement both interfaces. On the other side, you don't need to override all of the methods of the extended abstract class.
Also, this method works if you add the listeners to a container of your frame. However, it will behave as if that container is located at (0, 0). You'll have to add some offsets on setLocation()
.
Upvotes: 2
Views: 435
Reputation: 3589
Try this:
public class UndecoratedJFrame extends JFrame {
Point origin;
Point origin2;
public UndecoratedJFrame() {
setUndecorated(true);
initComponents();
setVisible(true);
}
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt);
}
});
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
formMouseDragged(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
pack();
}
private void formMouseDragged(java.awt.event.MouseEvent evt) {
origin2 = new Point(evt.getLocationOnScreen());
setLocation((int)(origin2.getX() - origin.getX()), (int)(origin2.getY() - origin.getY()));
}
private void formMousePressed(java.awt.event.MouseEvent evt) {
origin = new Point(evt.getPoint());
}
}
Upvotes: 1
Reputation: 324108
so I need a way to change the window position.
For a different approach check out Moving Windows.
Upvotes: 2