web-dev-qa-db-ja.com

Robot.mouseMoveが指定された場所に正しく移動しない

ロボットに対してmouseMoveコマンドを実行するたびに、マウスが常に同じ場所に移動するとは限りません。たとえば、次のコードがあります。

import Java.awt.Robot;
import Java.util.concurrent.TimeUnit;

public class MainBot {
    public static void main(String[] args){
        try {
            Robot screenWin = new Robot();
            TimeUnit.SECONDS.sleep(2);
            screenWin.mouseMove(100, 300);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

コードは通常、マウスをXに配置します。

Mouse Location after running 最初に、実行を押し(Eclipseを使用しています)、マウスを特定の場所に移動します(2秒のタイマーが切れる前)。次に、2秒の遅延が終了し、マウスが移動して、スクリプトが終了します。問題は、マウスが同じ正確な場所に2回移動することは決してないように見えることです。たとえば、マウスは(100, 300)に移動する必要がありますが、ほとんどの場合、(0, 300)のように見えます。ただし、最初にマウスをおおよその位置に移動すると、適切な場所に移動する場合もあります。

スクリーンショットのピクセル位置を取得するためにマウスがペイントを使用する必要がある場所を取得していますが、位置が変化し続けるため、それはないと思います。

mouseMoveの座標がどのように機能するかについて私が見逃しているものはありますか?

編集:基本的に、そのプログラムで開始を押してから、マウスを新しい位置に移動します(したがって、mouseMove関数の前に別の初期位置があります)その後、mouseMoveが実行されます。これを行うたびに、マウスは別の場所に移動します。

8
DarkHorse

OpenJDKには未解決のバグがあるため、これは関連している可能性があります。

https://bugs.openjdk.Java.net/browse/JDK-8196030?jql=project%20in%20(JDK)%20AND%20component%20in%20(client-libs)%20AND%20Subcomponent% 20in%20(Java.awt)

バグの詳細は、画面のスケーリングとmouse_move関数に関連して、Windows 10 FallCreatorsアップデートで問題が発生した可能性があることを示しています。

それまでの間、画面のスケールを125%ではなく100%に設定して、効果があるかどうかを確認してみてください。

2
Syl

解決策を見つけました。マウスを座標(0,0)に移動するだけで、目的の場所に移動できます。

2

適切なカーソル配置を行うためのクラスを作成しました。これは、Windows10のスケーリングでも機能します。

MoveMouseControlled(double、double)関数を使用して、カーソルを指定された位置に移動します。 [0,1]座標系を使用します。 (0,0)ポイントは、画面の左上隅です。

import Java.awt.AWTException;
import Java.awt.Dimension;
import Java.awt.MouseInfo;
import Java.awt.Point;
import Java.awt.Robot;
import Java.awt.Toolkit;

public class MouseCorrectRobot extends Robot
{
    final Dimension ScreenSize;// Primary Screen Size

    public MouseCorrectRobot() throws AWTException
    {
        super();
        ScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
    }

    private static double getTav(Point a, Point b)
    {
        return Math.sqrt((double) ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)));
    }

    public void MoveMouseControlled(double xbe, double ybe)// Position of the cursor in [0,1] ranges. (0,0) is the upper left corner
    {

        int xbepix = (int) (ScreenSize.width * xbe);
        int ybepix = (int) (ScreenSize.height * ybe);

        int x = xbepix;
        int y = ybepix;

        Point mert = MouseInfo.getPointerInfo().getLocation();
        Point ElozoInitPont = new Point(0, 0);

        int UgyanAztMeri = 0;
        final int UgyanAZtMeriLimit = 30;

        int i = 0;
        final int LepesLimit = 20000;
        while ((mert.x != xbepix || mert.y != ybepix) && i < LepesLimit && UgyanAztMeri < UgyanAZtMeriLimit)
        {
            ++i;
            if (mert.x < xbepix)
                ++x;
            else
                --x;
            if (mert.y < ybepix)
                ++y;
            else
                --y;
            mouseMove(x, y);

            mert = MouseInfo.getPointerInfo().getLocation();

            if (getTav(ElozoInitPont, mert) < 5)
                ++UgyanAztMeri;
            else
            {
                UgyanAztMeri = 0;
                ElozoInitPont.x = mert.x;
                ElozoInitPont.y = mert.y;
            }

        }
    }

}
1
Gats János

同様の問題が発生しました。それを解決するために、ループを実行しました。

  • テスト位置
  • 移動
  • テスト位置
  • oKでない場合は、もう一度移動します

そしてそれは常に2未満のループで動作します

Point pd = new Point(X,Y); // X,Y where mouse must go
int n = 0;
while ((!pd.equals(MouseInfo.getPointerInfo().getLocation())) && (++n <= 5))
{
    r.mouseMove(pd.x, pd.y);
}
0
Georges