将JFrame捕捉到屏幕边缘

时间:2014-01-20 11:19:33

标签: java swing window jframe

我将以&#34开头作为序言;这更像是一个答案"。

就像我一样,我自己回答这个问题。

我通过标签进行搜索,我使用Google搜索,我使用标签和明文的组合进行搜索(在此网站上),而无法找到这个来自。有些人粘贴源,或链接源,作为答案。

这是(其中一个)原始来源,它遍布整个网络。

http://bit.ly/1eYKNXS(code.google.com域名,我可以根据需要使用完整网址进行编辑)

它并不完美。 0的偏移量似乎总是起作用(在我的家用机器上进行测试,在这里,使用多显示器设置和不使用),而偏移量为5。它没有多显示器支持。快照行为有点令人兴奋(它继续发射)。

答案是这个问题的答案。随意锁定,存档等。只是试图帮助:)

1 个答案:

答案 0 :(得分:1)

所以,改进的代码。希望它对人们有所帮助,并且阅读不会太冗长或痛苦。

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;
    }

}