From Laggy to Smart: My Java App Learns to Click

Auto accept game for League of Legends built in Java

Insights

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Lessons

  • Always start with the messy version; it teaches you what not to do.

  • Optimising early is a trap. Fix only what slows you down.

  • Visual feedback helps debugging more than logs ever will.

Next, I’ll write about how I packaged it into a Windows .exe, polished the UI, and made it ready for everyday use.

Like what you see? There’s more.

Like what you see? There’s more.

Get monthly inspiration, blog updates, and creative process notes — handcrafted for fellow creators.

From Laggy to Smart: My Java App Learns to Click

Auto accept game for League of Legends built in Java

Insights

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Lessons

  • Always start with the messy version; it teaches you what not to do.

  • Optimising early is a trap. Fix only what slows you down.

  • Visual feedback helps debugging more than logs ever will.

Next, I’ll write about how I packaged it into a Windows .exe, polished the UI, and made it ready for everyday use.

Like what you see? There’s more.

Like what you see? There’s more.

Get monthly inspiration, blog updates, and creative process notes — handcrafted for fellow creators.

From Laggy to Smart: My Java App Learns to Click

Auto accept game for League of Legends built in Java

Insights

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

One night after a long day of sitting and working, I logged on to League to relax (trust me, it is not relaxing). I hit the Find Match button, then ran to the bathroom. If you’ve ever played League of Legends, you know it picks the worst time to show the “Match Accepted” screen. You have about 15 seconds before it auto-declines the game for you.

I missed that window. Got banned.

So I thought, I can automate this.

The Plan

I wanted to build a lightweight Java app that could:

  • Watch a fixed region of the screen

  • Detect when the Accept button appears

  • Click it automatically

I set three rules for myself:

  • Keep CPU use very low

  • No false positives

For tools, I chose:

  • Java 17, with JavaFX for the interface

  • java.awt.Robot for screen capture and mouse clicks

  • ScheduledExecutorService for the scanning loop

How It Works

  1. Capture a small region using Robot.createScreenCapture(rect)

  2. Convert it to grayscale and downscale for speed

  3. Compare it to the last captured frame

  4. If the pixel difference passes a set tolerance, trigger a click

Pseudocode looked something like this:

init UI, load settings

rect = selected region

robot = new Robot()

prev = null

stableHits = 0

every scanInterval ms:

img = robot.createScreenCapture(rect)

diff = meanAbsDiff(prev, img)

prev = img

if diff > tolerance:

stableHits++

else:

stableHits = 0

if stableHits >= debounceCount:

click(rect.center())

stableHits = 0

sleep(cooldown)

This small loop made all the difference. Instead of scanning the whole screen, it focused only on where the Accept button appears, saving a ton of resources.

Building Version 1

Version 1 was pure experimentation. I used raw Swing components, scanned the entire screen, and pushed my CPU to almost 100%. The app clicked when it shouldn’t have, lagged when it should’ve been idle, and stayed open even when I quit the game.

Still, it proved the idea worked.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Version 2: A Smarter Scanner

Built with Java 21JavaFX, and Maven, it uses java.awt.Robot to watch a chosen screen area and trigger a click when pixels match a reference or change past a set threshold.

Key upgrades:

  • Region picker overlay with live preview and click indicator

  • Adjustable tolerance, stride, and interval controls

  • Dual detection modes (reference match or change %)

  • Smooth, threaded scanning loop with safe start/stop

It runs on a lightweight MVC setup, stays responsive, and uses less CPU than V1.

Lessons

  • Always start with the messy version; it teaches you what not to do.

  • Optimising early is a trap. Fix only what slows you down.

  • Visual feedback helps debugging more than logs ever will.

Next, I’ll write about how I packaged it into a Windows .exe, polished the UI, and made it ready for everyday use.

Like what you see? There’s more.

Like what you see? There’s more.

Get monthly inspiration, blog updates, and creative process notes — handcrafted for fellow creators.

Create a free website with Framer, the website builder loved by startups, designers and agencies.