In: Computer Science
Enhancing a Movable Circle
File MoveCircle contains a program that uses CirclePanel to draw a
circle and let the user move it by pressing buttons. Save these
files to your directory and compile and run MoveCircle to see how
it works. Then modify the code in CirclePanel as follows:
1. Add mnemonics to the buttons so that the user can move the
circle by pressing the ALT-l, ALT-r, ALT-u, or ALT-d keys.
2. Add tooltips to the buttons that indicate what happens when the
button is pressed, including how far it is moved.
3. When the circle gets all the way to an edge, disable the
corresponding button. When it moves back in, enable the button
again. Note that you will need instance variables (instead of local
variables in the constructor) to hold the buttons and the panel
size to make them visible to the listener. Bonus: In most cases the
circle won’t hit the edge exactly; check for this (e.g., x<0)
and adjust the coordinates so it does.
Deliverables:
CirclePanel.java
//
******************************************************************
// MoveCircle.java
//
// Uses CirclePanel to display a GUI that lets the user move
// a circle by pressing buttons.
//
******************************************************************
import java.awt.*;
import javax.swing.*;
public class MoveCircle
{
public static void main(String[] args)
{
JFrame frame = new JFrame ("MoveCircle");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 300);
frame.getContentPane().add(new CirclePanel(400,300));
frame.setVisible(true);
}
}
//
******************************************************************
// CirclePanel.java
//
// A panel with a circle drawn in the center and buttons on
the
// bottom that move the circle.
//
******************************************************************
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class CirclePanel extends JPanel
{
private final int CIRCLE_SIZE = 50;
private int x, y;
private Color c;
//---------------------------------------------------------------
// Set up circle and buttons to move it.
//---------------------------------------------------------------
public CirclePanel(int width, int height)
{
// Set coordinates so circle starts in middle
x = (width/2)-(CIRCLE_SIZE/2);
y = (height/2)-(CIRCLE_SIZE/2);
c = Color.green;
// Need a border layout to get the buttons on the bottom
this.setLayout(new BorderLayout());
// Create buttons to move the circle
JButton left = new JButton("Left");
JButton right = new JButton("Right");
JButton up = new JButton("Up");
JButton down = new JButton("Down");
// Add listeners to the buttons
left.addActionListener(new MoveListener(-20, 0));
right.addActionListener(new MoveListener(20, 0));
up.addActionListener(new MoveListener(0, -20));
down.addActionListener(new MoveListener(0, 20));
// Need a panel to put the buttons on or they'll be on
// top of each other.
JPanel buttonPanel = new JPanel();
buttonPanel.add(left);
buttonPanel.add(right);
buttonPanel.add(up);
buttonPanel.add(down);
// Add the button panel to the bottom of the main panel
this.add (buttonPanel, "South");
}
//----------------------------------------------------------------
// Draw circle on CirclePanel
//----------------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
page.setColor(c);
page.fillOval(x,y, CIRCLE_SIZE, CIRCLE_SIZE);
}
//----------------------------------------------------------------
// Class to listen for button clicks that move circle.
//----------------------------------------------------------------
private class MoveListener implements ActionListener
{
private int dx;
private int dy;
//----------------------------------------------------------------
// Parameters tell how to move circle at click.
//----------------------------------------------------------------
public MoveListener(int dx, int dy)
{
this.dx = dx;
this.dy = dy;
}
//----------------------------------------------------------------
// Change x and y coordinates and repaint.
//----------------------------------------------------------------
public void actionPerformed(ActionEvent e)
{
x += dx;
y += dy;
repaint();
}
}
}
Here is the completed code for this problem. Comments are included, go through it, learn how things work and let me know if you have any doubts or if you need anything to change. If you are satisfied with the solution, please rate the answer. If not, PLEASE let me know before you rate, I’ll help you fix whatever issues. Thanks
//CirclePanel.java
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class CirclePanel extends JPanel {
private final int CIRCLE_SIZE = 50;
private int x, y;
private Color c;
// declaring buttons outside the constructor (for part 3)
private JButton left, right, up, down;
// ---------------------------------------------------------------
// Set up circle and buttons to move it.
// ---------------------------------------------------------------
public CirclePanel(int width, int height) {
// Set coordinates so circle starts in middle
x = (width / 2) - (CIRCLE_SIZE / 2);
y = (height / 2) - (CIRCLE_SIZE / 2);
c = Color.green;
// Need a border layout to get the buttons on the bottom
this.setLayout(new BorderLayout());
// initialize buttons to move the circle
left = new JButton("Left");
right = new JButton("Right");
up = new JButton("Up");
down = new JButton("Down");
// adding mnemonics to the buttons (for part 1)
left.setMnemonic('l');
right.setMnemonic('r');
up.setMnemonic('u');
down.setMnemonic('d');
// adding tool tips to the buttons (for part 2)
left.setToolTipText("circle will be moved 20 spaces to the left");
right.setToolTipText("circle will be moved 20 spaces to the right");
up.setToolTipText("circle will be moved 20 spaces up");
down.setToolTipText("circle will be moved 20 spaces down");
// Add listeners to the buttons
left.addActionListener(new MoveListener(-20, 0));
right.addActionListener(new MoveListener(20, 0));
up.addActionListener(new MoveListener(0, -20));
down.addActionListener(new MoveListener(0, 20));
// Need a panel to put the buttons on or they'll be on
// top of each other.
JPanel buttonPanel = new JPanel();
buttonPanel.add(left);
buttonPanel.add(right);
buttonPanel.add(up);
buttonPanel.add(down);
// Add the button panel to the bottom of the main panel
this.add(buttonPanel, "South");
}
// ----------------------------------------------------------------
// Draw circle on CirclePanel
// ----------------------------------------------------------------
public void paintComponent(Graphics page) {
super.paintComponent(page);
page.setColor(c);
page.fillOval(x, y, CIRCLE_SIZE, CIRCLE_SIZE);
}
// ----------------------------------------------------------------
// Class to listen for button clicks that move circle.
// ----------------------------------------------------------------
private class MoveListener implements ActionListener {
private int dx;
private int dy;
// ----------------------------------------------------------------
// Parameters tell how to move circle at click.
// ----------------------------------------------------------------
public MoveListener(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
// ----------------------------------------------------------------
// Change x and y coordinates and repaint.
// ----------------------------------------------------------------
public void actionPerformed(ActionEvent e) {
x += dx;
y += dy;
// (for part 3)
// if x goes beyond 0, disabling left button, else enabling it
if (x <= 0) {
left.setEnabled(false);
} else {
left.setEnabled(true);
}
// if x+CIRCLE_SIZE goes above screen width, disabling right button,
// else enabling it
if (x + CIRCLE_SIZE >= getWidth()) {
right.setEnabled(false);
} else {
right.setEnabled(true);
}
// repeating similar checks with up and down buttons
if (y <= 0) {
up.setEnabled(false);
} else {
up.setEnabled(true);
}
if (y + CIRCLE_SIZE >= getHeight()) {
down.setEnabled(false);
} else {
down.setEnabled(true);
}
repaint();
}
}
}
/*OUTPUT*/