I'm going to preface this with "this is more of an answer".
As in, I'm answering this myself.
I searched by tags, I searched with Google, I searched using a combination of tags and plaintext (on this site) and I still couldn't find the damn question that this originated from. Some guy pastes the source, or links the source, as an answer.
This is (one of the) original source(s), it's all over the web.
http://bit.ly/1eYKNXS (code.google.com domain, I can edit with full URL if necessary)
It's not perfect. The offset of 0 doesn't always seem to work (tested on my home machine and here, using a multi-monitor setup and without), while an offset of 5 does. It doesn't have multi-monitor support. The snap behaviour is a bit excitable (it keeps on firing).
Answer is the answer to this question. Feel free to lock, archive, etc. Just trying to help :)
So, behold, the improved code. Hope it helps people, and that it isn't too verbose or a pain to read.
package widgets;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
public class WindowSnapper extends ComponentAdapter {
private boolean locked = false;
// feel free to modify; set based on my own preferences
// incorporate as user option?
private int sd = 30;
private GraphicsDevice[] screenList = GraphicsEnvironment
.getLocalGraphicsEnvironment().getScreenDevices();
// clamping at 5 seems correct, 0 clamps at -5 beyond screen boundary
public void componentMoved(ComponentEvent evt) {
// gets current display device
Window myWindow = new Window((Frame) evt.getComponent());
GraphicsConfiguration config = myWindow.getGraphicsConfiguration();
GraphicsDevice myScreen = config.getDevice();
// matches against active display
for(GraphicsDevice gd : getScreenList()) {
// this will set the display to a new display if the window is moved to a new display
if(gd.equals(myScreen)) {
myScreen = gd;
break;
}
}
// minimising calls to stack
int screenWidth = myScreen.getDefaultConfiguration().getBounds().width;
int screenHeight = myScreen.getDefaultConfiguration().getBounds().height;
int compWidth = evt.getComponent().getWidth();
int compHeight = evt.getComponent().getHeight();
int nx = evt.getComponent().getX();
int ny = evt.getComponent().getY();
// setting offsets in case of different screen
int currentX = myScreen.getDefaultConfiguration().getBounds().x;
int currentY = myScreen.getDefaultConfiguration().getBounds().y;
// see end of method
// OR conditions seem to stabilise movement when close to screen edge
if(locked
|| nx == currentX + 5
|| ny == currentY + 5
|| nx == currentX + screenWidth - compWidth - 5
|| ny == currentY + screenHeight - compHeight - 5)
return;
// left
if(nx < (currentX + sd) && nx > (currentX + 5)) {
nx = currentX + 5;
}
// top
if(ny < (currentY + sd) && ny > (currentY + 5)) {
ny = currentY + 5;
}
// right
if(nx > currentX + screenWidth - compWidth - sd
&& nx < currentX + screenWidth - compWidth - 5) {
nx = currentX + screenWidth - compWidth - 5;
}
// bottom
if(ny > currentY + screenHeight - compHeight - sd
&& ny < currentY + screenHeight - compHeight - 5) {
ny = currentY + screenHeight - compHeight - 5;
}
// make sure we don't get into a recursive loop when the
// set location generates more events
locked = true;
evt.getComponent().setLocation(nx, ny);
locked = false;
}
public int returnSD() {
return sd;
}
public void setSD(int sd) {
this.sd = sd;
}
public GraphicsDevice[] getScreenList() {
return screenList;
}
public void setScreenList(GraphicsDevice[] screenList) {
this.screenList = screenList;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With