Draw a car when mouse clicked JAVA - java

I have 2D-Graphic class to draw the car and I really need help to make the car appear when I click on the mouse. This is what I have so far.
public class CarMove extends JComponent
{
private int lastX = 0;
private int x = 1;
//create the car from draw class
Car car1 = new Car(x,320);
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int carSpeed = 1;
int w = getWidth();
x = lastX + carSpeed;
if (x == w - 60)
{
x = x - carSpeed;
}
FrameMouseListener listener = new FrameMouseListener();
super.addMouseListener(listener);
lastX = x;
}
public class FrameMouseListener implements MouseListener
{
#Override
public void mouseClicked(MouseEvent e)
{
Graphics2D g2 = (Graphics2D) g;
car1.draw(g2);
}
}
}
I add the mouselistener to the frame when I click on the frame the car will appear but I cant make it work in mouseClicked event to draw the car

Your code should look more like:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
public class CarMove extends JComponent
{
private volatile boolean drawCar = false;
private int lastX = 0;
private int x = 1;
// create the car from draw class
Car car1 = new Car(x, 320);
{
FrameMouseListener listener = new FrameMouseListener();
super.addMouseListener(listener);
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int carSpeed = 1;
int w = getWidth();
x = lastX + carSpeed;
if (x == w - 60)
{
x = x - carSpeed;
}
if (drawCar)
{
car1.draw(g2);
}
lastX = x;
}
public class FrameMouseListener extends MouseAdapter
{
#Override
public void mouseClicked(MouseEvent e)
{
drawCar = true;
repaint();
}
}
}
First of all, you need to add your listener only once at startup.
Second, all drawing operations must be performed in painting mathods, you are not allowed to store the graphics object and draw to it from any place in your code. There is a special drawing thread, that may only touch this object. SO the rexcipe is, set up what should be painted (by some variables), prepare your painting method to properly use those variables, then call repaint() whern you would like to refresh the view.

Related

JPanel not showing up in another JPanel

I'm trying to make a 2D racing game here by adding a Jpanel on top of a Jpanel. This is done by using 2 classes which I have posted down below.
The problem is the car is never appears on the track... I'm really not sure what I'm missing.. any help is more than welcome!
Thank you in advance!
Car.java
public class Car extends JPanel implements Runnable
{
private static final long serialVersionUID = 007;
private BufferedImage car = null;
private float x = 100F, y = 100F;
private Thread driveThread = new Thread(this);
private double currentAngle = 0; // angel of the car
private static int[] key = new int[256]; // keyboard input
private float MAX_SPEED = 7F;
private float speed = 0F; // speed of our racing car
private float acceleration = 0.15F;
private int player;
private boolean playable = true;
public Car(int player)
{
this.player = player;
this.setSize(super.getHeight(), super.getWidth());
this.setFocusable(true); // enables keyboard
try
{
if (player == 1)
{
//red car
car = ImageIO.read(this.getClass().getResource(
"/imagesCar/first-0.png"));
System.out.println(car.getColorModel());
} else if(player == 2)
{
//blue car
car = ImageIO.read(this.getClass().getResource(
"/imagesCar/second-0.png"));
x = x +30;
}
} catch (IOException e) {
System.out.println("dupi");
}
// starts the drive thread
startGame();
}
private void startGame() {
driveThread.start();
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
this.setOpaque(false);
// rotation
Graphics2D g2d = (Graphics2D) g;
AffineTransform rot = g2d.getTransform();
// Rotation at the center of the car
float xRot = x + 12.5F;
float yRot = y + 20F;
rot.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(rot);
//Draws the cars new position and angle
g2d.drawImage(car, (int) x, (int) y, 50, 50, this);
}
protected void calculateCarPosition() {
//calculates the new X and Y - coordinates
x += Math.sin(currentAngle * Math.PI / 180) * speed * 0.5;
y += Math.cos(currentAngle * Math.PI / 180) * -speed * 0.5;
}
protected void carMovement() {
// Player One Key's
if (player == 1) {
if (key[KeyEvent.VK_LEFT] != 0) {
currentAngle-=2;
} else if (key[KeyEvent.VK_RIGHT] != 0) {
currentAngle+=2;
}
if (key[KeyEvent.VK_UP] != 0) {
if (speed < MAX_SPEED) {
speed += acceleration;
}
} else if (key[KeyEvent.VK_DOWN] != 0 && speed > -1) {
speed = speed - 0.1F;
}
speed = speed * 0.99F;
} else {
//Player Two Key's
if (key[KeyEvent.VK_A] != 0) {
currentAngle -= 2;
} else if (key[KeyEvent.VK_D] != 0) {
currentAngle += 2;
}
if (key[KeyEvent.VK_W] != 0) {
if (speed < MAX_SPEED) {
speed += acceleration;
}
} else if (key[KeyEvent.VK_S] != 0 && speed > -1) {
speed = speed - 0.1F;
}
//reduce speed when no key is pressed
speed = speed * 0.99F;
}
}
public void getUnderground() {
}
// get key events!
final protected void processKeyEvent(KeyEvent e) {
key[e.getKeyCode()] = e.getID() & 1;
}
#Override
public void run() {
while (true) {
repaint();
carMovement();
calculateCarPosition();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
RaceTrack.java
public class RaceTrack extends JPanel
{
#Override
public void paintComponent(Graphics g)
{
Color c1 = Color.green;
g.setColor(c1);
g.fillRect(150, 200, 550, 300);
Color c2 = Color.black;
g.setColor(c2);
g.drawRect(50, 100, 750, 500); // outer edge
g.drawRect(150, 200, 550, 300); // inner edge
Color c3 = Color.yellow;
g.setColor(c3);
g.drawRect(100, 150, 650, 400); // mid-lane marker
Color c4 = Color.white;
g.setColor(c4);
g.drawLine(425, 500, 425, 600); // start line
}
}
main
public static void main(String[] args) {
JFrame mainFrame = new JFrame();
mainFrame.setSize(850,650);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container content = mainFrame.getContentPane();
RaceTrack track = new RaceTrack();
Car carP1 = new Car(1);
track.add(carP1);
content.add(track);
mainFrame.setVisible(true);
}
Car has no defined sizing hints, so it's default size is 0x0
Adding Car to RaceTrack, which is using a FlowLayout will layout Car to it's preferred size of 0x0
Swing is not thread safe so you're probably have a bunch of thread race conditions/violations as well
Not sure if this is the proper way to solve this
Don't use components for this purpose, this problem just screams custom painting all the way.
There are plenty of blogs and tutorials about basic game development, so I don't want to spend a lot of time going over the same material.
Basically, what you want is to define a series of "attributes" to the objects you want to use in your game (AKA "entities"). Not all entities need to be paintable, some might trigger other actions or simply act as "markers" for other entities to use.
In this example, I'm defining two basic entities, "movable" and "paintable". A "paintable" entity may be static (ie the track) or "movable" (ie the car)
The intention is to provide a isolated concept of functionality which can easily be applied to a verity objects in order to "describe" their functionality and purpose within the game.
For example...
public interface MovableEntity extends Entity {
public void update(Rectangle bounds);
}
public interface PaintableEntity extends Entity {
public void paint(Graphics2D g2d, ImageObserver imageObserver, Rectangle bounds);
}
So, in your case, a Car is both Paintable and Movable.
Your "engine" would then maintain one or more lists of these "entities" and process them accordingly.
This example simply makes use of a Swing Timer to act as the "main loop"
mainLoop = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
// Lots of collision detection and other awesome stuff
for (MovableEntity entity : movableEntitys) {
entity.update(bounds);
}
repaint();
}
});
mainLoop.start();
This provides a level of thread safety, as the Timer is triggered within the context of the Event Dispatching Thread, meaning that while we're updating the entities, they can't be painted.
Then we simply make use of the JPanel's paintComponent method to act as the rendering process...
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
for (PaintableEntity paintable : paintableEntities) {
Graphics2D g2d = (Graphics2D) g.create();
paintable.paint(g2d, this, bounds);
g2d.dispose();
}
}
This is a pretty broad example based on demonstrating basic concepts in a simple manner. There are far more complex possible solutions which would follow the same basic principles.
Personally, I'd define some kind of "path" which acts as the track, on which the cars would then calculate there positions based on different factors, but that's somewhat of a more complex solution then is required right now. But if you're really interested, it might look something like this
Runnable Example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.ImageObserver;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
/*
You could have entities which can collide which have collision detection
capabilities
Some entities don't need to be painted and may provide things like
visual or audio affects
*/
public interface Entity {
}
public interface MovableEntity extends Entity {
public void update(Rectangle bounds);
}
public interface PaintableEntity extends Entity {
public void paint(Graphics2D g2d, ImageObserver imageObserver, Rectangle bounds);
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GamePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GamePane extends JPanel {
// Could use a single list and filter it, but hay
private List<PaintableEntity> paintableEntities;
private List<MovableEntity> movableEntitys;
private Timer mainLoop;
public GamePane() {
paintableEntities = new ArrayList<>(25);
movableEntitys = new ArrayList<>(25);
paintableEntities.add(new TrackEntity());
CarEntity car = new CarEntity();
paintableEntities.add(car);
movableEntitys.add(car);
mainLoop = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
// Lots of collision detection and other awesome stuff
for (MovableEntity entity : movableEntitys) {
entity.update(bounds);
}
repaint();
}
});
mainLoop.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle bounds = new Rectangle(0, 0, getWidth(), getHeight());
for (PaintableEntity paintable : paintableEntities) {
Graphics2D g2d = (Graphics2D) g.create();
paintable.paint(g2d, this, bounds);
g2d.dispose();
}
}
}
public class CarEntity implements PaintableEntity, MovableEntity {
private int delta = 1;
private int xDelta = 0;
private int yDelta = delta;
private int xPos = 2;
private int yPos = 2;
private int size = 4;
#Override
public void paint(Graphics2D g2d, ImageObserver imageObserver, Rectangle bounds) {
g2d.translate(bounds.x, bounds.y);
g2d.setColor(Color.RED);
g2d.fillRect(xPos - size / 2, yPos - size / 2, size, size);
}
#Override
public void update(Rectangle bounds) {
xPos += xDelta;
yPos += yDelta;
if (xPos + (size / 2) > bounds.x + bounds.width) {
xPos = bounds.x + bounds.width - (size / 2);
xDelta = 0;
yDelta = -delta;
} else if (xPos - (size / 2) < bounds.x) {
xPos = bounds.x + (size / 2);
xDelta = 0;
yDelta = delta;
}
if (yPos + (size / 2) > bounds.y + bounds.height) {
yPos = bounds.y + bounds.height - (size / 2);
xDelta = delta;
yDelta = 0;
} else if (yPos - (size / 2) < bounds.y) {
yPos = bounds.y + (size / 2);
xDelta = -delta;
yDelta = 0;
}
}
}
public class TrackEntity implements PaintableEntity {
#Override
public void paint(Graphics2D g2d, ImageObserver imageObserver, Rectangle bounds) {
g2d.translate(bounds.x, bounds.y);
g2d.setColor(Color.BLUE);
g2d.drawRect(2, 2, bounds.width - 4, bounds.height - 4);
}
}
}

Draw multiple car when click Java

I have written a program to draw 1 car when I click the mouse button, now I want to draw 1 more car when I click a second time on the mouse button.
#SuppressWarnings("serial")
public class CarMove extends JComponent
{
private volatile boolean drawCar = false;
private volatile boolean drawCar1 = false;
private int lastX = 0;
private int clickCount = 0;
{
FrameMouseListener listener = new FrameMouseListener();
super.addMouseListener(listener);
}
public CarMove()
{
Thread animationThread = new Thread(new Runnable()
{
public void run()
{
while (true)
{
repaint();
try
{
Thread.sleep(10);
} catch (Exception ex) {}
}
}
});
animationThread.start();
}
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
if (drawCar)
{
int x = 1;
int carSpeed = 1;
int w = getWidth();
x = lastX + carSpeed;
//create the car from draw class
Car car1 = new Car(x,320);
car1.draw(g2);
lastX = x;
}
if (drawCar1)
{
int x = 1;
int carSpeed = 1;
int w = getWidth();
x = lastX + carSpeed;
//create the car from draw class
Car car2 = new Car(x,320);
car2.draw(g2);
lastX = x;
}
}
public class FrameMouseListener implements MouseListener
{
#Override
public void mouseClicked(MouseEvent ev)
{
if (clickCount == 1)
{
drawCar = true;
repaint();
}
if (clickCount == 2)
{
drawCar1 = true;
repaint();
}
}
I try to create the boolean drawcar 2 times but It did not work please help me.
In case you need to know how many times the user clicked the mouseButton.
#Override
public void mouseReleased(MouseEvent m) {
int clickCount = m.getClickCount();
//change your code to do draw the cars based on clicks
}
Edit:
when you call repaint method always the first line must be:
super.repaint();
To draw multiple cars you have to use a loop when you call the paint(Graphics g) like:
public void paintComponent(Graphics g){
super.repaint();
Graphics2D g2 = (Graphics2D) g;
for(int car=0; car<totalClicks; car++){
//Here add your code to draw the cars
if(car==1){
//do this
}else if(car==2){
//do that
}else if(car== 3){
//do more
}else if(car==4){
//hard job
}//etc
}

How to use swing timer?

I'm trying to write a program that draws a new square every second. This is my code for my JPannel class. I have two other classes but I beleive they are irrelivant to my question. One has the main method where it creates an object of the other class that contains the JFrame. I just cant figure out how to get the timer to work and how it works.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Drawing extends JPanel implements ActionListener{
Drawing(){
super();
setBackground(Color.WHITE);
startTimer();
}
public void startTimer() {
Timer timer = new Timer(1000, this);
timer.start();
}
public void paintComponent(Graphics g) {
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.BLUE);
for(int x = 0; x < 999; x ++) {
for(int y = 0; y < 999; y ++) {
g.drawRect(0,0, x, y);
}
}
}
public void actionPerformed(ActionEvent e) {
repaint();
}
}
Get rid of the for loops in your paintComponent method. Note that painting methods should not change object state. Instead the timer's actionPerformed method gets repeatedly called -- advance your counter or x/y variables there, and then call repaint().
e.g.,
private int x;
private int y;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
// RECT_WIDTH etc are constants
g.drawRect(x, y, RECT_WIDTH, RECT_HEIGHT);
}
public void actionPerformed(ActionEvent e) {
int width = getWidth();
int height = getHeight();
// code here to change the object's state -- here to change
// location of the rectangle
x++;
y++;
// TODO: check that x and y are not beyond bounds and if so,
// then re-position them
repaint();
}

Drawing and storing objects by clicking the mouse button

I am trying to draw circle objects with each click and then store every circle object into an Arraylist, I don't know why my program is not working! If I removed the arraylist and the line that create a new circle object, the program will work. How would I make my program store all circuit objects into an Arraylist ?
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Random;
public class CircleObj extends JPanel {
private int rColor;
private int gColor;
private int bColor;
private int radius;
private Random rand = new Random();
private int xStart;
private int yStart;
ArrayList <Circle> xxx ;
public CircleObj () {
xxx = new ArrayList<Circle>();
addMouseListener(new MouseAdapter() {
public void mouseClicked (MouseEvent e) {
xStart = e.getX();
yStart = e.getY();
rColor = rand.nextInt(256);
gColor = rand.nextInt(256);
bColor = rand.nextInt(256);
radius = rand.nextInt(20);
repaint();
}
}); // end addMouseListener
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.setColor(new Color(rColor, gColor, bColor));
g.fillOval(xStart, yStart, radius, radius);
xxx.add(new Circle());
}
private class Circle {
private int x;
private int y;
private int r;
private int rcol;
private int gcol;
private int bcol;
public Circle()
{
x=xStart;
y=yStart;
r=radius;
rcol= rColor;
gcol= gColor;
bcol= bColor;
}
}
}
======
import javax.swing.JFrame;
import java.awt.BorderLayout;
public class HW3 {
public static void main (String[] arg) {
JFrame frame = new JFrame("Circles");
CircleObj canvas = new CircleObj();
frame.add(canvas, BorderLayout.CENTER);
frame.setBounds(250, 98, 600, 480);
//frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
} // end main
} //end HW3
Don't add the new shape inside the paintComponent method, paintComponent can be called for any number of reasons, many of which you don't control, instead, create it when the mouseClicked event is triggered...
public void mouseClicked (MouseEvent e) {
xStart = e.getX();
yStart = e.getY();
rColor = rand.nextInt(256);
gColor = rand.nextInt(256);
bColor = rand.nextInt(256);
radius = rand.nextInt(20);
xxx.add(new Circle(xStart, yStart, new Color(rColor, gColor, bColor), radius));
repaint();
}
And then in your paintComponent, loop through the ArrayList and paint the circles...
public void paintComponent (Graphics g) {
super.paintComponent(g);
for (Circle c : xxx) {
g.setColor(c.getColor());
g.fillOval(c.getX(), c.getY(), c.getRadius(), c.getRadius());
}
}
Now, you're going to have to modify you Circle class to provide getters which the CircleObj can use in order to actually paint the circles...
Alternatively, you could make use of the Shapes API provided within Java...Have a look at Working with Geometry for more details...

Java:: Use a mouse listener object in a different class

Hello people,
I am trying to write an animated character for a multitouch screen. I want my object to have 5 eyes and each of whose pupil to be dragged and dropped differently, within the eye of course.
I have tried to do it all in a single class and the problem seems to be assigning mouse handlers to each of the five pupils! In other words, if I move one pupil, all the pupils are moving.
Then, I resorted to using a bespoke class just to the pupil. When I use it by itself, the pupil is draggable. However, when I use it as an object in the eyes class, the pupil is static! No clicks registered, no mouse activity tracked.
I have looked at tutorials, other related issues with mouse handlers and could not make any progress. I changed the code a dozen times from various tutorials and suggestions before finally posting here. Any ideas where I am missing the cue? Any pointers would be greatly appreciated.
Thanks in advance.
PS: I know I am yet to put the constraints on the pupil movement within the eye.
Code for main eyes class:
package rollEyes;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FiveEyes extends JPanel
{
private static final long serialVersionUID = 1L;
private static final int SIZE = 512;
private int a = SIZE / 2;
private int b = a;
private int r = 4 * SIZE / 5;
private int n;
int circleSize=30;
Pupil dc = new Pupil(1);
public FiveEyes(int n)
{
super(true);
this.setPreferredSize(new Dimension(SIZE, SIZE));
this.n = n;
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
a = getWidth() / 2;
b = getHeight() / 2;
int m = Math.min(a, b);
r = 4 * m / 5;
int r2 = Math.abs(m - r) / 2;
int numOfEyes = 5;
for (int i = 0; i < numOfEyes ; i++)
{
Graphics2D g2d2 = (Graphics2D) g;
double t = 2 * Math.PI * i / n;
int x = (int) Math.round(a + r * Math.cos(t));
int y = (int) Math.round(b + r * Math.sin(t));
drawEyeSockets(g2d2, x,y, 2*r2,2*r2);
}
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
create();
}
});
}
public void drawEyeSockets(final Graphics2D g2, int x, int y, int w, int h)
{
g2.drawOval(x,y,w,h);
dc.drawCircle(g2, x+12, y+12);
}
private static void create()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FiveEyes fivey = new FiveEyes(5);
f.add(fivey);
f.pack();
f.setVisible(true);
}
}
Code for the Pupil class:
package rollEyes;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Pupil extends JPanel
{
private static final long serialVersionUID = 1L;
int radius=50;
int x_after = 50;
int y_after = 50;
MouseHandler mh ;
private static int n =1;
public Pupil(int n)
{
super(true);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
drawCircle(g2d,x_after,y_after);
}
public void drawCircle(final Graphics2D g2d, int x, int y)
{
g2d.setColor(Color.BLUE);
g2d.fillOval(x, y, radius/2, radius/2);
mh = new MouseHandler();
this.addMouseListener(mh);
this.addMouseMotionListener(mh);
}
private static void create()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Pupil dc = new Pupil(n);
f.add(dc);
f.pack();
f.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
create();
}
});
}
private class MouseHandler extends MouseAdapter
{
boolean circleClicked=false;
public void mouseReleased(MouseEvent e)
{
circleClicked = false;
}
public void mousePressed(MouseEvent me)
{
circleClicked = true;
}
public void mouseDragged(MouseEvent me)
{
if (circleClicked)
{
x_after = me.getX();
y_after = me.getY();
repaint();
}
}
}
}
You have Pupil extend JPanel, but really shouldn't be doing that. Instead, use the concepts that you've learned in your current Pupil class -- how to draw a movable circle, and extend it in the larger FiveEyes class, only this time create a List<Pupil> and draw them. My suggestions:
Make Pupil not extend JPanel. Instead give it the machinery to draw circles in certain locations and to have that location changed.
Also you will need to give it a way to recognize if its circle has been clicked by giving it a contains(Point p) method. One way to do this is to use a Shape object, or you can roll your own method.
Give FiveEyes a List<Pupil> that in reality is an ArrayList<Pupil> and fill it with Pupil objects.
In FiveEyes paintComponent(...) method, iterate through this List telling each Pupil to draw itself.
In your FiveEyes MouseAdapter's mousePressed(...) method, iterate through your Pupil List to see if a Pupil has been clicked on. If so, move it.
Alternatively, you could create a Pupil BufferedImage, put it into an ImageIcon, and put that into a JLabel, and then allow your FiveEyes class's MouseAdapter to drag the labels around.
First of all, this code
mh = new MouseHandler();
this.addMouseListener(mh);
this.addMouseMotionListener(mh);
must only be called once. You're adding millions of mouse handlers to the component!
And you need five instances of Pupil, one for each eye. Right now, you have only one, so of course the rendering will only yield one result.
Lastly, you must make sure that only one eye is "active" at a time (i.e. not all of them should receive mouse events or not all of them should process them).

Categories