Skip to content

Commit e91ac8d

Browse files
committed
Merge branch 'feature-mouse-circular-move' into 'master'
Feature: Add new circular movement for mouse pointer See merge request group-bear/mouse-automove!2
2 parents b70a500 + 47401e4 commit e91ac8d

14 files changed

+337
-87
lines changed

README.md

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,37 @@ Since download was blocked, so anti-idle application could not be downloaded and
99
Therefore, the app was born, so that I could make a coffee with ease of mind.
1010

1111
## Introduction
12-
**mouse-automove** is simple Java application that uses Java AWT **Robot API** to move mouse randomly.
13-
- Pure Java 8 SDK only, without any other API library.
12+
**mouse-automove** is a simple Java application that uses Java AWT **Robot API** to move the mouse pointer.
13+
- Pure Java 8 SDK only, without any other 3rd party API library.
1414
- Shutdown hook to close the timer properly with its queued task.
1515
- Pause / resume the timer with 'p' keyboard input.
16+
- Exit the application 'e' keyboard input.
1617

18+
## Features
1719
### Randomization Features
18-
- Randomize the interval in seconds for each mouse movement, between 15 seconds to 60 seconds.
19-
- Currently, two types of mouse movement set:
20-
- Mouse moved at random point on screen.
21-
- Mouse moved at edge of screen.
22-
- Mouse move randomly:
23-
- Random number of movement per, between 3 and 10.
24-
- Random point on screen but linked from previous.
25-
- Mouse move on edge:
26-
- Move from current mouse position to edge of screen.
20+
- Randomize the interval in seconds for each mouse pointer movement, between 15 seconds to 60 seconds.
21+
- Currently, three types of mouse pointer movement set:
22+
- Mouse pointer moved to random point on screen.
23+
- Mouse pointer moved at edge of screen.
24+
- Mouse pointer moved in circular motion from middle point of screen.
25+
26+
### Movement
27+
- Mouse pointer move randomly:
28+
- Random number of movement per set, between 3 and 10.
29+
- Random point on screen, but each will be linked from previous.
30+
- Return to original mouse pointer position when finished.
31+
- Mouse pointer move on edge:
32+
- Move mouse pointer from current position to top left corner of screen.
2733
- Move to each corner of screen, and make it a round.
2834
- Random number of round, between 1 and 3.
29-
- Return to original mouse position when finished.
35+
- Return to original mouse pointer position when finished.
36+
- Mouse pointer move in circular motion:
37+
- Move mouse pointer from current position to the middle of screen.
38+
- Radius of circle is calculated based on screen height and width.
39+
- Move to 0<sup>o</sup> along positive x-axis, based on radius.
40+
- Move in full circular motion from 0<sup>o</sup> until 360<sup>o</sup>.
41+
- Random number of circular round, between 1 and 3.
42+
- Return to middle of screen and back to original mouse pointer position when finished.
3043

3144
## Java API
3245
Significant Java SDK API that was used:
@@ -50,11 +63,14 @@ Script folder was provided with batch/shell scripts to compile and run.
5063
./script/run.bat
5164
./script/run.sh
5265
```
53-
Type 'p' in console and press 'Enter' to pause or resume.
66+
67+
During application started:
68+
- Type 'p' in console and press 'Enter' to pause or resume.
69+
- Type 'e' in console and press 'Enter' to exit.
5470

5571
## Development
5672
Next plan:
57-
- Create a mouse move to perform circular motion from center screen.
73+
- Create configurable properties for number of intervals, random step, and rounds for edge and circular movement.
5874

5975
Pull request are welcome. Do contact me to learn more.
6076

src/com/aizuddindeyn/mouse/MouseApplication.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,47 +4,46 @@
44
*/
55
package com.aizuddindeyn.mouse;
66

7-
import java.text.MessageFormat;
8-
import java.util.Scanner;
7+
import java.awt.AWTException;
8+
import java.util.concurrent.Executors;
9+
import java.util.concurrent.ScheduledExecutorService;
10+
import java.util.concurrent.TimeUnit;
911

1012
/**
1113
* @author aizuddindeyn
1214
* @date 11/7/2020
1315
*/
1416
public class MouseApplication {
1517

16-
private static final Scanner SCANNER = new Scanner(System.in);
18+
private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor();
1719

1820
public static void main(String[] args) {
1921
MouseUtils.log("Starting application");
2022

2123
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
2224
MouseInstance.getInstance().stop();
23-
SCANNER.close();
25+
MousePrompt.getScanner().close();
26+
EXECUTOR.shutdown();
2427
MouseUtils.log("Stopping application");
2528
}));
2629

30+
try {
31+
MouseRobot.init();
32+
} catch (AWTException ex) {
33+
MouseUtils.logErr("Failed to initialize robot: " + ex.getMessage());
34+
Runtime.getRuntime().exit(1);
35+
}
36+
2737
MouseInstance.getInstance().start();
2838

29-
while (true) {
30-
try {
31-
String status = (MouseInstance.getInstance().isStarted()) ? "started" : "paused";
32-
String action = (MouseInstance.getInstance().isStarted()) ? "pause" : "resume";
33-
System.out.println();
34-
System.out.print(MessageFormat.format("App {0}. Press 'p' and Enter to {1}: ", status, action));
35-
String input = SCANNER.next();
36-
// Type 'p' to pause or resume
37-
if ((input != null && !input.isEmpty()) && 'p' == input.charAt(0)) {
38-
if (MouseInstance.getInstance().isStarted()) {
39-
MouseInstance.getInstance().stop();
40-
} else {
41-
MouseInstance.getInstance().start();
42-
}
43-
}
44-
45-
} catch (Exception ex) {
46-
MouseUtils.logErr(ex.getMessage());
47-
}
39+
EXECUTOR.schedule(new MouseRunnable(EXECUTOR), MouseUtils.EXECUTOR_DELAY, TimeUnit.MILLISECONDS);
40+
}
41+
42+
static void startStop(boolean started) {
43+
if (started) {
44+
MouseInstance.getInstance().stop();
45+
} else {
46+
MouseInstance.getInstance().start();
4847
}
4948
}
5049
}

src/com/aizuddindeyn/mouse/MouseInstance.java

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,54 @@
44
*/
55
package com.aizuddindeyn.mouse;
66

7-
import java.util.HashMap;
8-
import java.util.Map;
97
import java.util.Timer;
108

119
/**
1210
* @author aizuddindeyn
1311
* @date 11/7/2020
1412
*/
15-
public class MouseInstance {
13+
class MouseInstance {
1614

1715
private static final MouseInstance INSTANCE = new MouseInstance();
1816

19-
private static final Map<Integer, MouseMove> MOVE_MAP = new HashMap<>();
20-
2117
private Timer timer;
2218

2319
private boolean started = false;
2420

25-
static {
26-
MOVE_MAP.put(1, new MouseMoveRandom());
27-
MOVE_MAP.put(2, new MouseMoveEdge());
28-
}
29-
3021
private MouseInstance() {
3122
// Singleton
3223
}
3324

34-
public static MouseInstance getInstance() {
25+
static MouseInstance getInstance() {
3526
return INSTANCE;
3627
}
3728

38-
public synchronized void start() {
29+
synchronized void start() {
3930
timer = new Timer();
4031
MouseUtils.log("Timer started");
4132

42-
new MouseTask(timer, INSTANCE).run();
4333
started = true;
34+
timer.schedule(new MouseTask(timer, INSTANCE), 1500L);
4435
}
4536

46-
public synchronized void stop() {
37+
synchronized void stop() {
4738
timer.cancel();
4839
started = false;
4940
MouseUtils.log("Timer stopped");
5041
}
5142

52-
public void execute() {
43+
void execute() {
5344
try {
54-
int type = MouseRandom.getSecureRandom().nextInt(MOVE_MAP.size()) + 1;
55-
MouseMove move = MOVE_MAP.get(type);
56-
if (move != null) {
57-
MouseUtils.log("Move: " + move.getClass().getSimpleName());
58-
move.move();
59-
}
45+
int index = MouseRandom.getSecureRandom().nextInt(MouseMoveEnum.getEnumMap().size());
46+
MouseMoveEnum enums = MouseMoveEnum.values()[index];
47+
MouseMoveEnum.getEnumMap().get(enums).move();
6048

6149
} catch (Exception ex) {
6250
MouseUtils.logErr(ex.getMessage());
6351
}
6452
}
6553

66-
public synchronized boolean isStarted() {
54+
synchronized boolean isStarted() {
6755
return started;
6856
}
6957
}

src/com/aizuddindeyn/mouse/MouseMove.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,24 @@
1111
* @author aizuddindeyn
1212
* @date 11/7/2020
1313
*/
14-
public interface MouseMove {
14+
interface MouseMove {
1515

1616
void move() throws Exception;
1717

18-
default void moveMouse(Point origin, Point target) throws Exception {
19-
Robot robot = new Robot();
18+
default void move(Point origin, Point target) throws Exception {
2019
double dx = (target.getX() - origin.getX()) / MouseUtils.MOVE_TIMES;
2120
double dy = (target.getY() - origin.getY()) / MouseUtils.MOVE_TIMES;
2221
double dt = 1;
2322
for (int step = 1; step < MouseUtils.MOVE_TIMES; step++) {
2423
Thread.sleep((int) dt);
2524
int x = ((int) (origin.getX() + dx * step));
2625
int y = ((int) (origin.getY() + dy * step));
27-
robot.mouseMove(x, y);
26+
move(new Point(x, y));
2827
}
2928
}
29+
30+
default void move(Point target) throws Exception {
31+
Robot robot = MouseRobot.getInstance();
32+
robot.mouseMove(target.x, target.y);
33+
}
3034
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Owned by aizuddindeyn
3+
* Visit https://gitlab.com/group-bear/mouse-automation
4+
*/
5+
package com.aizuddindeyn.mouse;
6+
7+
import java.awt.Dimension;
8+
import java.awt.Point;
9+
10+
import static com.aizuddindeyn.mouse.MouseUtils.CIRCLE_ROUND_MAX;
11+
12+
/**
13+
* @author aizuddindeyn
14+
* @date 11/7/2020
15+
*/
16+
class MouseMoveCircular implements MouseMove {
17+
18+
@Override
19+
public void move() throws Exception {
20+
Point original = MouseUtils.getMouseLocation();
21+
Dimension screen = MouseUtils.getScreenResolution();
22+
23+
// Calculating best radius based on screen size
24+
int radiusOnHeight = screen.height / 3;
25+
int radiusOnWidth = screen.width / 3;
26+
int radius = Math.min(radiusOnHeight, radiusOnWidth);
27+
28+
int round = MouseRandom.getSecureRandom().nextInt(CIRCLE_ROUND_MAX) + 1;
29+
30+
int midX = (screen.width / 2) + 1;
31+
int midY = (screen.height / 2) + 1;
32+
Point center = new Point(midX, midY);
33+
34+
move(original, center);
35+
36+
Dimension firstPoint = calculateCircle(0, radius);
37+
move(center, new Point(center.x + firstPoint.width, center.y + firstPoint.height));
38+
39+
for (int i = 1; i <= 360 * round; i++) {
40+
Thread.sleep(10);
41+
Dimension d = calculateCircle(i, radius);
42+
move(new Point(center.x + d.width, center.y + d.height));
43+
}
44+
45+
move(MouseUtils.getMouseLocation(), center);
46+
move(center, original);
47+
}
48+
49+
Dimension calculateCircle(int degree, int radius) {
50+
double rad = Math.toRadians(degree);
51+
double x = radius * (Math.cos(rad));
52+
double y = radius * (Math.sin(rad));
53+
54+
return new Dimension((int) x, (int) y);
55+
}
56+
}

src/com/aizuddindeyn/mouse/MouseMoveEdge.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* @author aizuddindeyn
1717
* @date 11/7/2020
1818
*/
19-
public class MouseMoveEdge implements MouseMove {
19+
class MouseMoveEdge implements MouseMove {
2020

2121
@Override
2222
public void move() throws Exception {
@@ -25,7 +25,6 @@ public void move() throws Exception {
2525
Dimension screen = MouseUtils.getScreenResolution();
2626

2727
int round = MouseRandom.getSecureRandom().nextInt(EDGE_ROUND_MAX) + 1;
28-
MouseUtils.log("Round: " + round);
2928

3029
List<Point> targets = new ArrayList<>();
3130
for (int i = 1; i <= round; i++) {
@@ -39,7 +38,7 @@ public void move() throws Exception {
3938

4039
Point current = p;
4140
for (Point target : targets) {
42-
moveMouse(current, target);
41+
move(current, target);
4342
current = target;
4443
}
4544
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Owned by aizuddindeyn
3+
* Visit https://gitlab.com/group-bear/mouse-automation
4+
*/
5+
package com.aizuddindeyn.mouse;
6+
7+
import java.util.EnumMap;
8+
import java.util.Map;
9+
10+
/**
11+
* @author aizuddindeyn
12+
* @date 11/7/2020
13+
*/
14+
public enum MouseMoveEnum {
15+
16+
RANDOM(new MouseMoveRandom()),
17+
18+
EDGE(new MouseMoveEdge()),
19+
20+
CIRCLE(new MouseMoveCircular()),
21+
;
22+
23+
private static final Map<MouseMoveEnum, MouseMove> ENUM_MAP = new EnumMap<>(MouseMoveEnum.class);
24+
25+
private final MouseMove move;
26+
27+
static {
28+
for (MouseMoveEnum e : MouseMoveEnum.values()) {
29+
ENUM_MAP.put(e, e.getMove());
30+
}
31+
}
32+
33+
MouseMoveEnum(MouseMove move) {
34+
this.move = move;
35+
}
36+
37+
MouseMove getMove() {
38+
return move;
39+
}
40+
41+
static Map<MouseMoveEnum, MouseMove> getEnumMap() {
42+
return ENUM_MAP;
43+
}
44+
}

src/com/aizuddindeyn/mouse/MouseMoveRandom.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* @author aizuddindeyn
1515
* @date 11/7/2020
1616
*/
17-
public class MouseMoveRandom implements MouseMove {
17+
class MouseMoveRandom implements MouseMove {
1818

1919
@Override
2020
public void move() throws Exception {
@@ -24,7 +24,6 @@ public void move() throws Exception {
2424

2525
int step = RANDOM_STEP_MIN +
2626
(MouseRandom.getSecureRandom().nextInt(RANDOM_STEP_MAX - RANDOM_STEP_MIN) + 1);
27-
MouseUtils.log("Step: " + step);
2827

2928
int x = p.x;
3029
int y = p.y;
@@ -35,9 +34,10 @@ public void move() throws Exception {
3534
y2 = MouseRandom.getSecureRandom().nextInt(screen.height);
3635
} while (x2 == x && y2 == y);
3736

38-
moveMouse(new Point(x, y), new Point(x2, y2));
37+
move(new Point(x, y), new Point(x2, y2));
3938
x = x2;
4039
y = y2;
4140
}
41+
move(MouseUtils.getMouseLocation(), p);
4242
}
4343
}

0 commit comments

Comments
 (0)