use multithreading to complete this please include comments
use multithreading to complete this, please include comments if at all possible
For this problem you will need to create a GUI that allows a user to see a planet orbiting around a star. You will need to use the Java Swing components, as well as the ExecutorService so that your application is multithreaded.Solution
You can use this code to complete your application:-
Create file SolarSystem.java
compile it by javac -Xlint SolarSystem.java
Run java SolarSystem
import java.awt.*;
 import java.awt.geom.*;
 import javax.swing.*;
 import javax.swing.event.*;
 import java.util.*;
 import java.awt.event.*;
 import java.io.*;
/**
 * This class is used to make the spatial coordinates more transparent.
 */
 class Coord {
 /**
 * X represents the horizontal dimension which is measured from LHS
* of GUI. Y represents the vertical dimension which is measured
* from top of GUI.
 */
 public static final byte X = 1, Y = 0;
 }
/**
* Main entry into program. Creates GUI and repaints it in infinite loop.
 */
public class SolarSystem {
/**
* The time increment for numerical integration of differential equations
* governing motion in the solar system.
 */
 private static double dt = 0.001;
 /**
 * Default constructor.
 */
 public SolarSystem() { }
 /**
 * Main entry point into program. User may input number of planets
 * on command line.
 */
 public static void main(String[] arguments) {
 SkyFrame skyFrame;
 int numOfPlanets = 9;
if (arguments.length == 0)
 skyFrame = new SkyFrame(numOfPlanets, dt);
 else {
 if (arguments[0].equals(\"h\")) {
 System.exit(1);
 skyFrame = new SkyFrame(0, 0);
 }
 try {
 numOfPlanets = Integer.parseInt(arguments[0]);
 numOfPlanets = (int)Math.abs(numOfPlanets);
 skyFrame = new SkyFrame(numOfPlanets, 0);
 }
 catch(Exception e) {
 System.err.println(e.toString());
 System.exit(0);
 skyFrame = new SkyFrame(0, 0);
 }
 }
while (true) {
 skyFrame.getPanel().repaint();
 }
 }
 /**
 * The method getColor is used by the sattelites of the solar system
 * to get their color.
 */
 public static Color getColor(int i) {
 Color color;
 int j = i%8;
switch(j) {
 case 0 : color = Color.red;
 break;
 case 1: color = Color.blue;
 break;
 case 2 : color = Color.green;
 break;
 case 3 : color = Color.pink;
 break;
 case 4: color = Color.orange;
 break;
 case 5: color = Color.cyan;
 break;
 case 6 : color = Color.magenta;
 break;
 case 7 : color = Color.lightGray;
 break;
 default : color = Color.gray;
 }
 return color;
 }
   
 }
/**
 * Class Stars defines a group of stars that are displayed at random
 * locations. The stars are yellow circles that change diameter to simulate
 * twinlking.
*/
 class Stars {
 /**
 * Coordinates of the stars relative to the Sun\'s position.
 */
 private double[] xPos, yPos;
 /**
 * Initial diameter of the stars.
 */
 private double diameter = 5;
 /**
 * Number of stars.
 */
 private int numOfStars;
 /**
 * The Sun at the center of the solar system.
 */
 private Sun sun;
 public Stars(int mNumOfStars,
 double maxRadius,
 double minRadius,
 Sun mSun) {
 numOfStars = (int)Math.abs(mNumOfStars);
 xPos = new double[numOfStars];
 yPos = new double[numOfStars];
 maxRadius = Math.abs(maxRadius);
 minRadius = Math.abs(minRadius);
 sun = mSun;
if (minRadius == 0)
 minRadius += sun.getDiameter();
 //
 // Chose positions for each star at random between max and min radius.
 //
 for (int i = 0; i < numOfStars; ++i) {
 xPos[i] = (float)Math.random()*maxRadius;
 float yMin = xPos[i] > minRadius ?
 0 :
 (float)Math.sqrt(minRadius*minRadius - xPos[i]*xPos[i]);
 float yMax = (float)Math.sqrt(maxRadius*maxRadius -
 xPos[i]*xPos[i]);
 yPos[i] = (float)Math.random()*(yMax - yMin) + yMin;
 if (Math.random() > 0.5)
 xPos[i]*= -1;
 if (Math.random() > 0.5)
 yPos[i]*= -1;
 }
 }
 /**
 * The method draw displays the stars.
 */
 public void draw(Graphics2D comp2D) {
 comp2D.setColor(Color.yellow);
//
 // Make stars twinkle by chosing random diameter for each star.
 //
for (int i = 0; i < numOfStars; ++i) {
 double actualDia = diameter*Math.random();
Ellipse2D.Double starShape =
 new Ellipse2D.Double(xPos[i]/
 SkyFrame.getScaleFactor() +
 sun.getAbsPos(Coord.X),
 yPos[i]/SkyFrame.getScaleFactor() +
 sun.getAbsPos(Coord.Y),
 actualDia,
 actualDia);
 comp2D.fill(starShape);
 }
 }
 }
 /**
 * The interface host defines the interface needed for an object to serve
 * as a host about which a satellite may orbit.
 */
 interface Host {
 /**
 * The method getAbsPos calculates the absolute position of the
 * Host. This is the position used to display the Host
 * and is taken with respect to the upper left corner of the display.
 */
 public double getAbsPos(byte mAxis);
 /**
 * The method getMass returns the mass of the Host in arbitrary
 * units.
 */
 public double getMass();
 }
 /**
 * The abstract class Satellite defines satellites that orbit about a Sun.
 
 */
 abstract class Satellite implements Host{
 /**
 * The x and y coordinates of the Satellite\'s position.
 */
 protected double xPos, yPos;
 /**
 * The x and y components of the Satellite\'s velocity.
 */
 protected double xVel = 0, yVel = 0;
 /**
 * The x and y components of the Satellite\'s acceleration.
 */
 protected double xAcc = 0, yAcc = 0, dt;
 /**
 * The diameter of the Satellite.
 */
 protected double diameter;
 /**
 * The mass of the Satellite (arb. units).
 */
 protected double mass;
 /**
 * The color of the Satellite
 */
 protected final Color color;
 /**
 * The Host about which the Satellite orbits.
 */
 protected Host host;
 /**
 * Constructor for Satellite objects.
 */
 public Satellite(double mDt,
 double mDiameter,
 double mRadius,
 Color mColor,
 double mMass,
 Host mHost){
 dt = mDt;
 diameter = mDiameter;
 mass = mMass;
 color = mColor;
 host = mHost;
 //
 // The satellite\'s coordinates (xPos, yPos) relative to the
 // coordinates of the host satellite.
 //
 xPos = Math.random()*mRadius;
 yPos = Math.sqrt(mRadius*mRadius - xPos*xPos);
 //
 // Choose at random from the four Cartesian quadrants for the
 // intial position.
 //
 if (probOneHalf())
 xPos*= -1;
 if (probOneHalf())
 yPos*= -1;
 }
 /**
 * The method probOneHalf returns true with probability 1/2, otherwise
 * returns false.
 */
 protected boolean probOneHalf() {
 return Math.random() > 0.5;
 }
 /**
 * The method getAbsPos calculates the absolute position of the
 * Satellite. This is the position used to display the Satellite
 */
 public double getAbsPos(byte mAxis) {
 if (mAxis == Coord.X)
 return xPos/SkyFrame.getScaleFactor() + host.getAbsPos(mAxis);
 else
 return yPos/SkyFrame.getScaleFactor() + host.getAbsPos(mAxis);
 }
 /**
 * The getRelPosScaled calculate the relative position of the Satellite
 * scaled by the scale factor of the SkyFrame.
 */
 protected double getRelPosScaled(byte mAxis) {
 if (mAxis == Coord.X)
 return xPos/SkyFrame.getScaleFactor();
 else
 return yPos/SkyFrame.getScaleFactor();
 }
 /**
 * The method getRelPosUnscaled calculates the relative position of
 * the Satellite without scaling.
 */
 protected double getRelPosUnscaled(byte mAxis) {
 if (mAxis == Coord.X)
 return xPos;
 else
 return yPos;
 }
 /**
 * The method getTheta returns the angular position of the Satellite.
 */
 public double getTheta() {
 double theta = Math.atan(yPos/xPos);
 if (xPos < 0)
 theta = Math.PI + theta;
 else if (xPos > 0 && yPos < 0)
 theta = 2*Math.PI + theta;
 return theta;
 }
 /**
 * The method getVel calculates a Cartesian component of the Satellite\'s
 */
 public double getVel(byte mAxis) {
 if (mAxis == Coord.X)
 return xVel;
 else
 return yVel;
 }
 /**
 * The method getAcc calculates a Cartesian component of the Satellite\'s
 */
 public double getAcc(byte mAxis) {
 if (mAxis == Coord.X)
 return xAcc;
 else
 return yAcc;
 }
 /**
 * The abstract method translate calculates the displacement of the
 * Satellite as a function of time and updates the Satellite\'s
 * coordinates xPos and yPos.
 */
 public abstract void translate();
 /**
 * The method getDiameter returns the Satellite\'s diameter.
 */
 public double getDiameter() {
 return diameter;
 }
 /**
 * The method getColor returns the Satellite\'s color.
 */
 public Color getColor() {
 return color;
 }
 /**
 * The method getMass returns the Satellite\'s mass (arb. units).
 */
 public double getMass() {
 return mass;
 }
 /**
 * The method draw displays the Satellite.
 */
 public void draw(Graphics2D comp2D) {
 double zoomedDiameter = diameter/SkyFrame.getScaleFactor();
 Ellipse2D.Double form =
 new Ellipse2D.Double((int)(getAbsPos(Coord.X) - zoomedDiameter/2),
 (int)(getAbsPos(Coord.Y) - zoomedDiameter/2),
 (int)zoomedDiameter,
 (int)zoomedDiameter);
 comp2D.setColor(color);
 comp2D.fill(form);
 }
 }
 /**
 * Class Planet extends Satellite @see Satellite and implements the planets
 * that revolve about the Sun @see Sun. A Planet is given an initial
 * position and velocity and follows Newton\'s laws of motion.
 */
 class Planet extends Satellite {
 /**
 * An array of int\'s used to indicate the previous positions of the planet.
 * Used to plot the trajectory of the planet. The array is filled and
 * the index of the current position is tracked.
 */
 private int[] prevXPos, prevYPos;
 /**
 * Used to index into the position arrays to indicate the current position
 * of the planet.
 */
 private int currPosition = 0;
 /**
 * Counts the number of transaltions the Planet undergoes.
 */
 private int count = 0;
 /**
 * Determines the number of translations between which the position of
 * the Planet is recorded.
 */
 private int recordPosition = 5;
 /**
 * Indicates when we must loop back to the beginning of the previous
 * position array
 */
 private boolean looped = false;
 /**
 * The maximum number of previous positions that are recorded.
 */
 private final int maxPrevPositions = 128;
 /**
 * Total energy of the planet.
 */
 private final double TE;
 /**
 * The actual number of moons orbiting around the planet.
 */
 private final byte numOfMoons;
 /**
 * The maximum number of moons that may orbit around the planet.
 */
 private final byte maxNumOfMoons = 4;
 /**
 * The array of moons that orbit around the planet.
 */
 private Moon[] moon;
 /**
 * The panel in which the planet is displayed.
 */
 private SkyPanel hostPanel;
 public Planet(double mDt,
 double mDiameter,
 double mRadius,
 Color mColor,
 double mMass,
 SkyPanel mHostPanel,
 Host mHost ){
 super(mDt, mDiameter, mRadius, mColor, mMass, mHost);
 hostPanel = mHostPanel;
 prevXPos = new int[maxPrevPositions];
 prevYPos = new int[maxPrevPositions];
for (int i = 0; i < maxPrevPositions; ++i)
 prevXPos[i] = prevYPos[i] = 0;
numOfMoons = (byte)(Math.random()*maxNumOfMoons);
if (numOfMoons > 0) {
 moon = new Moon[numOfMoons];
 for (int i = 0; i < numOfMoons; ++i)
 moon[i] = new Moon(dt, // Time increment for calculating motion.
 Math.random()*6 + 3, // Moon\'s diameter.
 diameter*(1 + 0.2*Math.random()),// Radius of orbit.
 this); // Host about which moon orbits.
 }
double distToHost = Math.sqrt(getRelPosUnscaled(Coord.X)*
 getRelPosUnscaled(Coord.X) +
 getRelPosUnscaled(Coord.Y)*
 getRelPosUnscaled(Coord.Y));
 //
 // For calculating the force due to gravity, we set the universal
 // gravitational constant to one (or incorporate it into the sun\'s
 // mass).
 //
 double forceDueToGravity = host.getMass()*mass/
 (distToHost*distToHost);
 double theta = getTheta();
 //
 // The following formula for the velocity ensures that the
 // planet\'s initial motion about the sun is circular.
 //
 yVel = Math.sqrt(host.getMass()/distToHost)*
 Math.sin(theta + Math.PI/2);
 xVel = Math.sqrt(host.getMass()/distToHost)*
 Math.cos(theta + Math.PI/2);
xAcc = forceDueToGravity*Math.cos(theta + Math.PI)/mass;
 yAcc = forceDueToGravity*Math.sin(theta + Math.PI)/mass;
 //
 // Record the initial total energy of planet.
 //
 TE = mass*(xVel*xVel + yVel*yVel)/2 +
 mass*Math.sqrt(xAcc*xAcc + yAcc*yAcc)*distToHost;
 }
 /**
 * The method translate calculates the motion of the planet by numerically
 * integrating Newton\'s laws of motion.
 */
 public void translate() {
 double force, distToHost, theta;
for (int i = 0; i < 1/dt; ++i) {
 distToHost = Math.sqrt(getRelPosUnscaled(Coord.X) *
 getRelPosUnscaled(Coord.X) +
 getRelPosUnscaled(Coord.Y) *
 getRelPosUnscaled(Coord.Y));
force = mass*host.getMass()/(distToHost*distToHost);
 theta = getTheta();
 //
 // Calculate new acceleration.
 //
 xAcc = force*Math.cos(theta + Math.PI)/mass;
 yAcc = force*Math.sin(theta + Math.PI)/mass;
 //
 // Calculate new position using the original velocity.
 //
 xPos+= xVel*dt + dt*dt*xAcc/2;
 yPos+= yVel*dt + dt*dt*yAcc/2;
 //
 // Calculate new velocity.
 //
 xVel+= xAcc*dt;
 yVel+= yAcc*dt;
if (hostPanel.showPos())
 recordPosition();
 //
 // Translate the moons orbiting around the planet.
 //
 for (int j = 0; j < numOfMoons; ++j)
 moon[j].translate();
 }
 }
 /**
 * The method recordPosition records the current position of the planet
 * in the arrays prevXPos and prevYPos.
 */
 private void recordPosition() {
 if (++count > (int)(recordPosition/dt)) {
 count = 0;
 if (currPosition == maxPrevPositions) {
 currPosition = 0;
 looped = true;
 }
prevXPos[currPosition] = (int)getRelPosUnscaled(Coord.X);
 prevYPos[currPosition++] = (int)getRelPosUnscaled(Coord.Y);
 }
 }
 /**
 * The method getKE returns the kinetic energy of the planet in arbitrary
 * units.
 */
 public double getKE() {
 return mass*(xVel*xVel + yVel*yVel)/2;
 }
 /**
 * The method getPE returns the potential energy of the planet in arbitrary
 * units.
 */
 public double getPE() {
 return mass*Math.sqrt(xAcc*xAcc + yAcc*yAcc)*
 Math.sqrt(xPos*xPos + yPos*yPos);
 }
 /**
 * The method getTE returns the total energy of the planet in arbitrary
 * units.
 */
 public double getTE() {
 return TE;
 }
 /**
 * The method draw displays the Planet in scaled units of pixels.
 */
 public void draw(Graphics2D comp2D) {
 double zoomedDiameter = diameter/SkyFrame.getScaleFactor();
 //
 // Draw the night-time semi-circle of the planet.
 //
 comp2D.setColor(Color.darkGray);
 comp2D.fill(semiCircle(getAbsPos(Coord.X),
 getAbsPos(Coord.Y),
 zoomedDiameter,
 getTheta() + 3*Math.PI/2));
 //
 // Draw the day-time semi-circle of the planet.
 //
 comp2D.setColor(color);
 comp2D.fill(semiCircle(getAbsPos(Coord.X),
 getAbsPos(Coord.Y),
 zoomedDiameter,
 getTheta() + Math.PI/2 ));
 //
 // Show previous positions of the planet if requested by hostPanel.
 //
 if (hostPanel.showPos())
 drawPrevPositions(comp2D);
 //
 // Draw the moons orbiting around the planet.
 //
 for (int i = 0; i < numOfMoons; ++i)
 moon[i].draw(comp2D);
 }
 /**
 * The method drawPrevPositions draws the previous positions of the planet
 * by placing dots to indicate it\'s path.
 * @param comp2D The Graphics2D object used for the display.
 */
 private void drawPrevPositions(Graphics2D comp2D) {
 int end;
 int x, y;
 if (looped)
 end = maxPrevPositions;
 else
 end = currPosition;
for (int i = 0; i < end; ++i) {
 x = prevXPos[i]/SkyFrame.getScaleFactor() +
 (int)host.getAbsPos(Coord.X);
 y = prevYPos[i]/SkyFrame.getScaleFactor() +
 (int)host.getAbsPos(Coord.Y);
 comp2D.fill( new Ellipse2D.Float(x, y, 1, 1));
 }
 }
 /**
 * The method erasePrevPostions removes the dots indicating the previous
 * position of the planet from the screen.
 */
 public void erasePrevPositions() {
 looped = false;
 currPosition = 0;
 count = 0;
 }
 /**
 * The method semiCircle is used to draw a day-time and night-time
 * semi-circle of the planet with respect to the Host about which
 * the planet orbits.
 */
 private Area semiCircle(double x, double y, double dia, double theta) {
 double xp = x - dia/2;
 double yp = y - dia/2;
 Ellipse2D.Double circle = new Ellipse2D.Double(xp, yp, dia, dia);
 Rectangle2D.Double rect = new Rectangle2D.Double(xp, yp, dia, dia/2);
 Area semiCircleArea = new Area(circle);
 Area rectArea = new Area(rect);
 semiCircleArea.subtract(rectArea);
 semiCircleArea.transform(AffineTransform.
 getRotateInstance(theta, x, y));
 return semiCircleArea;
 }
 }
 /**
 * The class Moon defines a moon which executes pure circular motion about
 * it\'s host, so the formulas for calculating position are simplified compared
 * to those used for calculating planetary motion about the sun.
 */
 class Moon extends Satellite {
 /**
 * Constructor.
 */
 public Moon(double mDt,
 double mDiameter,
 double mRadius,
 Host mHost)
 {
 super(mDt, mDiameter, mRadius, Color.lightGray, (double)1, mHost);
 }
 /**
 * The method translate calculates the motion of the moon. Since moons
 * are only allowed to undergo circular motion, the calculation is
 * simplified compared to planetary motion.
 */
 public void translate() {
 double r, theta;
 //
 // Find radial position of moon.
 //
 r = Math.sqrt(getRelPosUnscaled(Coord.X)*getRelPosUnscaled(Coord.X) +
 getRelPosUnscaled(Coord.Y)*getRelPosUnscaled(Coord.Y));
 //
 // Calculate new angular position which is old old angular position
 // plus speed multiplied by delta t. The number 1000 is an arbitrary
 // number chosen to give the moons a convenient angular speed of orbit
 // (it is not related to any othe part of the program).
 //
 theta = getTheta() + Math.sqrt(1000*host.getMass()/(r*r*r))*dt;
 //
 // Convert angular position to Cartesian coordiantes.
 //
 xPos = r*Math.cos(theta);
 yPos = r*Math.sin(theta);
 }
 }
 /**
 * The class Sun extends Satellite @see Satellite and defines the origin
 * about which all planets orbit in the solar system. It is yellow and
 * has rays of random length eminatting from it.
 */
 class Sun extends Satellite {
 public Sun(double mDiameter,
 double mMass,
 double mXPos,
 double mYPos) {
 super((double)1,
 mDiameter,
 (double)0,
 Color.yellow,
 mMass,
 (Host)null);
xPos = mXPos;
 yPos = mYPos;
 }
 /**
 * The method getAbsPos returns the absolute position of the Sun in pixels.
 */
 public double getAbsPos(byte mAxis) {
 if (mAxis == Coord.X)
 return xPos;
 else
 return yPos;
 }
 /**
 * The methos setMass allows the user to set the mass of the sun in order
 * to observe the effects on planetary motion. The mass is measured in
 * arbitray units.
 */
 public void setMass(double newMass) {
 diameter*=newMass/mass;
 mass = newMass;
 }
 /**
 * The method draw displays the Sun in scaled units of pixels.
 * Sun.
 */
 public void draw(Graphics2D comp2D) {
 super.draw(comp2D);
BasicStroke pen = new BasicStroke(2F);
 comp2D.setStroke(pen);
double xf, yf;
double zoomedDiameter = diameter/SkyFrame.getScaleFactor();
 //
 // Draw rays of sun.
 //
 for (int i = 0; i < 10; ++i) {
 if (probOneHalf())
 xf = xPos+ Math.random()*zoomedDiameter*1.5;
 else
 xf = xPos - Math.random()*zoomedDiameter*1.5;
if (probOneHalf())
 yf = yPos + Math.random()*zoomedDiameter*1.5;
 else
 yf = yPos - Math.random()*zoomedDiameter*1.5;
Line2D.Double ray = new Line2D.Double(xPos,
 yPos,
 xf,
 yf);
 }
 }
 public void translate() {} // Sun does not move.
 }













