Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Minimal Submitted Files: You are required, but not limited, to turn in the follo

ID: 3556097 • Letter: M

Question

Minimal Submitted Files:

You are required, but not limited, to turn in the following source files:

Assignment12.java (It is complete)
ControlPanel.java (It extends JPanel, to be completed)
BallPanel.java (It extends JPanel)

You may add more classes or more methods than they are specified.

Skills to be Applied:

Swing/AWT

Classes may be needed:  
Animation/Multi-Threads
Timer in javax.swing package, JApplet, JButton, Container, JPanel, JLabel, JSlider, Color, Graphics, ActionListener (java.awt.event), ActionEvent (java.awt.event), ChangeListener (javax.swing.event), ChangeEvent (javax.swing.event). You may use other classes.

Program Description

Suggested Class Diagram: (.ppt file is available for this figure)

Write a Java program that constructs an Applet.

The JApplet of your program should contain ten buttons, "Up Red", "Down Red", "Left Red", "Right Red", "Stop Red", "Up Blue", "Down Blue", "Left Blue", "Right Blue", and "Stop Blue". On the right hand side of the buttons, add two sliders with labels at the top of each slider. On the right side of the sliders, add two panels showing a red ball moving on the cyan background, and the other panel showing a blue ball moving on the yellow background. Your graphical user interface should be similar to the picture below.

When the balls hit the end of the panel, they reverse their direction. A user can stop, change its direction to up, down, left, or right, and change their speed by using the sliders.

(The size of the applet here is approximately 450 X 300).

You need to create the following classes.

BallPanel class

BallPanel class extends JPanel class. It is used to define a panel where a ball is moving. It has the following additional attributes:

Attribute name

Attribute type

Description

x

Int

x-coordinate of the starting point of the ball's movement.

y

Int

y-coordinate of the starting point of the ball's movement.

ballColor

Color

color of the ball.

backColor

Color

background color of the panel

timer

Timer

An object of Timer in javax.swing package. This is used to control the ball's movement.

delay

Int

delay of the timer.

stepX

Int

each step that the ball moves in the horizontal direction. It is initialize to 3.

stepY

Int

each step that the ball moves in the vertical direction. It is initialize to 0.

CIRCLE_DIAMETER

final int

the diameter of the ball. It is set to 20.

The following constructor should be provided:

public BallPanel(int x, int y, Color ballColor, Color backColor)

x, y, ballColor, and backColor are initialized to the values of four parameters. delay should be initialized to 20, stepX should be initialized to 3, and stepY should be initialized to 0. The background should be set to the color that the variable "backColor" contains. Timer should be instantiated with "delay" and the listener object created from MovingBallListener class. Then it should start by calling start() method in the constructor.

The following method should be implemented:

public void up()

Because we want the ball to start moving up, we set stepX to 0 and stepY to -3. The timer should start again using its start method.

public void down()

Because we want the ball to start moving down, we set stepX to 0 and stepY to 3. The timer should start again using its start method.

public void left()

Because we want the ball to start moving left, we set stepX to -3 and stepY to 0. The timer should start again using its start method.

public void right()

Because we want the ball to start moving right, we set stepX to 3 and stepY to 0. The timer should start again using its start method.

public void suspend()

The timer should stop using its stop method.

public void setDelay(int delayNum)

This method set the delay of the timer using its parameter.

public void paintComponent(Graphics page)

A color of the ball should be set, and a ball should be drawing using the (x,y) coordinate and CIRCLE_DIAMETER.

MovingBallListener class

This class can be defined as a private class inside the BallPanel class. It implements ActionListener interface.

public void actionPerformed(ActionEvent event)

Its actionPerformed method implements how the ball should move by adding stepX and stepY to the corresponding variable, and re-paint the BallPanel after such change. In case the ball hits the side of the panel, it needs to reverse its direction. The width of the panel can be obtained by "getSize().getWidth()". For instance, you can check if the ball hits the right hand side wall by:

if (x > getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)

You should make use of methods such as up(), down(), left(), and right() created above.

ControlPanel class

The ControlPanel extends the JPanel class. It contains 10 buttons including two up buttons, two down buttons, two left buttons, two right buttons, and two stop buttons. It also contains two labels, two sliders, and two objects of the BallPanel class, one for the red ball and one for the blue ball.
You may create as many JPanel as you need to organize components using different layout managers.

The following constructor should be provided:

public ControlPanel(int width, int height)

Its parameters are width and height of the applet. It should instantiate each components and arrange them using layout managers. Add ButtonListener to each button, and add SliderListener to each slider.

ButtonListener class

This is a private class inside the ControlPanel. It implements ActionListener interface.

public void actionPerformed(ActionEvent event)

Its actionPerformed method defines an action for each button (There are 10 buttons). To distinguish buttons, you can use getSource() method of the ActionEvent object. For example, if "stop1" is the stop button for the red ball, here is how to check if that button is pushed:

public void actionPerformed(ActionEvent event)
{
   if (event.getSource() == stop1)
    {
    ...
    }
}

SliderListener class

This class is a private class inside the ControlPanel too. It implements ChangeListener interface. You need to provide code for the following method:

public void stateChanged(ChangeEvent event)
by getting the selected value of each slider, and assign it as a delay of the corresponding ball panel.

Grading Policy:

1.        1 point: All 10 buttons, 2 labels, and 2 sliders are shown in the panel.

2.        1 point: Balls are moving in the correct directions and have correct colors (red and blue).

3.        3 point: Up, Down, Left, and Right buttons are working.

4.        1 point: Stop buttons are working (When it is pushed, the corresponding ball stops).

5.        2 point: Sliders are working (When it is moved, the corresponding ball changes its speed/delay).

Attribute name

Attribute type

Description

x

Int

x-coordinate of the starting point of the ball's movement.

y

Int

y-coordinate of the starting point of the ball's movement.

ballColor

Color

color of the ball.

backColor

Color

background color of the panel

timer

Timer

An object of Timer in javax.swing package. This is used to control the ball's movement.

delay

Int

delay of the timer.

stepX

Int

each step that the ball moves in the horizontal direction. It is initialize to 3.

stepY

Int

each step that the ball moves in the vertical direction. It is initialize to 0.

CIRCLE_DIAMETER

final int

the diameter of the ball. It is set to 20.

Explanation / Answer

Hi here is the code that will help you....may not be complete but it will get you started...

//ControlPanel class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.JFrame;

public class ControlPanel extends JPanel
{

   private BallPanel ball1, ball2;
   //declare all your components here
   private JButton upR, downR, leftR, rightR, stopR, upB, downB, leftB, rightB, stopB;
   private JSlider delayR, delayB;
   private BallPanel redC, blueC;
   private int DIAMETER = 30;
   private JPanel redButtons, blueButtons, sliderR, sliderB, top, bottom, left, canvasCY;
   private JLabel redDelay, blueDelay;

public ControlPanel(int width, int height)
   {
       width = 450;
       height = 300;

       //create 2 ball panels
        redC = new BallPanel(0,10,Color.red,Color.cyan);
        blueC = new BallPanel(0,10,Color.blue,Color.yellow);


      //create 10 buttons
     upR = new JButton("Up Red");
     downR = new JButton("Down Red");
     leftR = new JButton("Left Red");
     rightR = new JButton("Right Red");
     stopR = new JButton("Stop Red");
     upB = new JButton("Up Blue");
     downB = new JButton("Down Blue");
     leftB = new JButton("Left Blue");
     rightB = new JButton("Right Blue");
     stopB = new JButton("Stop Blue");

      //create 2 sliders
    delayR=new JSlider(SwingConstants.VERTICAL,0,50,25);
    delayB=new JSlider(SwingConstants.VERTICAL,0,50,25);

       //add the corresponding listener to sliders and buttons
        upR.addActionListener(new ButtonListener());
        downR.addActionListener(new ButtonListener());
        leftR.addActionListener(new ButtonListener());
        rightR.addActionListener(new ButtonListener());
        stopR.addActionListener(new ButtonListener());
        upB.addActionListener(new ButtonListener());
        downB.addActionListener(new ButtonListener());
        leftB.addActionListener(new ButtonListener());
        rightB.addActionListener(new ButtonListener());
        stopB.addActionListener(new ButtonListener());

       //organize 5 buttons into a panel using grid layout
        redButtons= new JPanel(new GridLayout(5,1));
        redButtons.add(upR);
        redButtons.add(downR);
        redButtons.add(leftR);
        redButtons.add(rightR);
        redButtons.add(stopR);

       //organize 5 buttons into a panel using grid layout
        blueButtons= new JPanel(new GridLayout(5,1));
        blueButtons.add(upB);
        blueButtons.add(downB);
        blueButtons.add(leftB);
        blueButtons.add(rightB);
        blueButtons.add(stopB);

       //create 2 labels
        redDelay = new JLabel("Red Ball Delay");
        blueDelay = new JLabel("Blue Ball Delay");
       //organize a label and a slider into a panel using border layout
        sliderR = new JPanel(new BorderLayout());
        sliderR.add(redDelay, BorderLayout.NORTH);
        sliderR.add(delayR, BorderLayout.SOUTH);
       //organize the panel containing buttons and the panel with a slider
        top = new JPanel(new GridLayout(1,2));
        top.add(redButtons);
        top.add(sliderR);
       //organize a label and a slider into a panel using border layout
        sliderB = new JPanel(new BorderLayout());
        sliderB.add(blueDelay, BorderLayout.NORTH);
        sliderB.add(delayB, BorderLayout.SOUTH);
       //organize the panel containing buttons and the panel with a slider
        bottom = new JPanel(new GridLayout(1,2));
        bottom.add(blueButtons);
        bottom.add(sliderB);

        left=new JPanel(new GridLayout(2,1));
        left.add(top);
        left.add(bottom);

        canvasCY = new JPanel(new GridLayout(2,1));
        canvasCY.add(redC);
        canvasCY.add(blueC);

        JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left, canvasCY);
        setLayout(new GridLayout(0,1));
        add(sp);
        sp.setVisible(true);

    }


//The ButtonListener class defines actions to be taken in case
//each of 10 buttons are pushed.
private class ButtonListener implements ActionListener
   {
       public void actionPerformed(ActionEvent event)
        {
            Object action = event.getSource();

            //if the up button for the red ball is pushed.

             if (event.getSource() == upR)
                            redC.up();
                        else if (event.getSource() == downR)
                            redC.down();
                        else if (event.getSource() == leftR)
                            redC.left();
                        else if (event.getSource() == rightR)
                            redC.right();
                        else if (event.getSource() == stopR)
                            redC.suspend();

            if (event.getSource() == upB)
                            blueC.up();
                        else if (event.getSource() == downB)
                            blueC.down();
                        else if (event.getSource() == leftB)
                            blueC.left();
                        else if (event.getSource() == rightB)
                            blueC.right();
                        else if (event.getSource() == stopB)
                            blueC.suspend();
         }
     } //end of ButtonListener

   //The SliderListener defines actions to be taken in case
   //each of the 2 sliders is moved by a user
   private class SliderListener implements ChangeListener
    {
        public void stateChanged(ChangeEvent event)
         {

         }

     } //end of SliderListener

}

//BallPanel class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import java.awt.Color;
import java.awt.Graphics;

public class BallPanel extends JPanel
    {
        int x;
        int y;
        Color ballColor;
        Color backColor;
        Timer timer;
        int delay;
        int stepX=3;
        int stepY=0;
        final int CIRCLE_DIAMETER = 20;

        public BallPanel(int x, int y, Color ballColor, Color backColor)
        {
            this.x=x;
            this.y=y;
            this.ballColor=ballColor;
            this.backColor=backColor;
            delay=20;
            stepX=3;
            stepY=0;
            timer= new Timer(delay, new MovingBallListener());
            timer.start();
            repaint();
            }
        public void up()
        {
            stepX=0;
            stepY=-3;
            repaint();
            }
        public void down()
        {
            stepX=0;
            stepY=3;
            repaint();
            }
        public void left()
        {
            stepX=-3;
            stepY=0;
            repaint();
            }
        public void right()
        {
            stepX=3;
            stepY=0;
            repaint();
            }
        public void suspend()
        {
            stepX=0;
            stepY=0;
            repaint();
            }
        public void setDelay(int delayNum)
        {
            timer.setDelay(delayNum);
            }
        public void paintComponent(Graphics page)
        {
            super.paintComponent(page);

            page.setColor(ballColor);
           page.fillOval(x,y,CIRCLE_DIAMETER,CIRCLE_DIAMETER);          
            setBackground(backColor);
            }
        private class MovingBallListener implements ActionListener
                {
        public void actionPerformed(ActionEvent event)
        {
            if (x > getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
                    stepX=-3;
                    stepY=0;
                    repaint();

            if(x < getSize().getWidth()-CIRCLE_DIAMETER && stepY == 0)
                    stepX=3;
                    stepY=0;
                    repaint();
            }
        }
        }