How do you make a shape slide on a JFrame?

I have some simple code that draws a dot in one of 8 places on a screen. There is a higher chance the dot will appear in some locations more than others. The code works and all, but it feels kind of weird that the dot is teleporting from one location to the other. I would like for the dots to slide in a circle that I have drawn, can someone please help me out?

Here is my code:

  package com.company;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class Main extends JPanel {

private static JFrame frame = new JFrame();
private static int random = 1;

public static void main(String[] args) {

//Time -= 5 every time used
Runnable number = () -> random = (int) (Math.random() * 100) + 1;
ScheduledExecutorService executor1 = Executors.newScheduledThreadPool(1);
executor1.scheduleWithFixedDelay(number, 0, 1, TimeUnit.SECONDS);
frame.getContentPane().add(new Main());
frame.setSize(2000, 1080);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.WHITE);
frame.setVisible(true);
frame.setResizable(true);
}

public void paint(Graphics g2) {
Graphics2D g = (Graphics2D) g2;
if (random > 0 && random <= 15) {
g.fillOval(920, 3, 100, 100);

} else if (random > 15 && random <= 20) {
g.fillOval(920, 797, 100, 100);

} else if (random > 20 && random <= 35) {
g.fillOval(523, 400, 100, 100);

} else if (random > 35 && random <= 50) {
g.fillOval(1317, 400, 100, 100);

} else if (random > 50 && random <= 65) {
g.fillOval(620, 143, 100, 100);

} else if (random > 65 && random <= 80) {
g.fillOval(1220, 143, 100, 100);

} else if (random > 80 && random <= 90) {
g.fillOval(620, 657, 100, 100);

} else if (random > 90 && random <= 100) {
g.fillOval(1220, 657, 100, 100);
}
g.drawOval(570, 50, 800, 800);
frame.repaint();
}
}

• No offense and kinda unrelated, but WHY ON EARTH are you using swing? That was already outdated when I was in highschool being forced to learn it. JavaFX is so much smoother with everything. It also has a ton of built-in animation features and stuff – Hobbamok Feb 7 at 13:23
• Really? But why are there still so much people using swing and so many swing questions on stack overflow? – Laser Infinite Feb 7 at 22:41
• Why are so many people still using bitcoin despite it being one of the worst cryptocurrencies out there? Because it's so widespread. Teachers learned it when they did their CS class and some refuse to update and so they still teach their students this outdated stuff. Also, it still works so many people don't bother – Hobbamok Feb 9 at 23:01

Your Situation

You have created a Runnable that is executed with the freuqency of one/second.

This runnable does nothing else but setting a new value for your int random and redraws that value.

Solution

What you have to do is to change your Runnable so that is does the animation for you. (I would suggest to make a method that creates the Runnable for you.) Your new Runnable should split the time for the animation into proper pieces and draw each of it.

Let's do some math first:

time for animation: 1s
framerate: 25 f/s
frameDuration: 40ms

using this result you create a new Runnable:

public static Runnable createAnimationRunnable(){
return () -> {

setTarget();//see text below
for(int i = 0; i < 25; i++){ //25 frames within that second duration runnable

double percentage = i/25d; //percentage - alias progress
drawAnimation(percentage);
try {
Thread.sleep(40); //frame duration
} catch (InterruptedException e) {
//please handle properly!!!
}
}

};
}


this Runnable will now call static void drawAnimation(double percentage){} 25 time within that one second of runtime.

Now you have to use this drawAnimation to move your spot from one location to the other. To achieve this you have to store the previous location and the target location. I have already inserted the code that creates the data required for that, it's the method setTarget() in your Runnable. Note: i strongly advise you to use proper data type as for now i will introduce a Point to represent your spot

private static Point previous = new Point(0,0);
private static Point target = new Point(0,0);
private static Point animationPoint = new Point(0,0); //see text below

public static void setTarget(){
previous = target;
target = new Point(Math.random()*100, Math.random()*100));
}


At this point we know where to start the animation and we know where to stop the Animation, we have now already the time slots to draw. what's left is to create the animation steps:

static void drawAnimation(double percentage){
double dx = percentage * (end.x-start.x); //x-way to target, in percent
double dy = percentage * (end.y-start.y);
animationPoint = new Point(start.x + dx, start.y + dy); //a small step for a man
frame.repaint(); //i'll get in hell for this
}


When you paint you just have to draw the Point animationPoint and you have to no longer to the math during painting - it is already done before drawing.

Unsolved problems

I am not sure what you understand by draw a CIRCLE ANIMATION and hence i displayed a line animation. it's up to you to change this animation into the code that does, what you want.

• What I mean by circle animation is getting the dot to move along the circle like a train on a railroad. A line animation seems pretty easy if you think about it. – Laser Infinite Feb 7 at 22:55