dragging object using MouseListener Java applet - java

I'm trying to create an applet that draws a circle (defined as an object) to the screen then this circle can be dragged across the screen using the mouse. So far when the mouse is pressed the object is drawn and can be dragged, but what I want it to do is draw the object when the applet is started then allow the user to click on the object and drag it. Any help or clues would be much appreciated. here is the code:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class sheepDog extends Applet implements ActionListener, MouseListener, MouseMotionListener
{
manAndDog dog;
int xposR;
int yposR;
public void init()
{
addMouseListener(this);
addMouseMotionListener(this);
}
public void paint(Graphics g)
{
dog.display(g);
}
public void actionPerformed(ActionEvent ev)
{}
public void mousePressed(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mouseMoved(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{}
public void mouseDragged(MouseEvent e)
{
dog = new manAndDog(xposR, yposR);
xposR = e.getX();
yposR = e.getY();
repaint();
}
}
class manAndDog implements MouseListener, MouseMotionListener
{
int xpos;
int ypos;
int circleWidth = 30;
int circleHeight = 30;
Boolean mouseClick;
public manAndDog(int x, int y)
{
xpos = x;
ypos = y;
mouseClick = true;
if (!mouseClick){
xpos = 50;
ypos = 50;
}
}
public void display(Graphics g)
{
g.setColor(Color.blue);
g.fillOval(xpos, ypos, circleWidth, circleHeight);
}
public void mousePressed(MouseEvent e)
{
mouseClick = true;
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mouseMoved(MouseEvent e)
{}
public void mouseClicked(MouseEvent e)
{}
public void mouseDragged(MouseEvent e)
{
if (mouseClick){
xpos = e.getX();
ypos = e.getY();
}
}
}
Thanks

In the start method of your applet, assign a location for the manAndDog object and call repaint
Reimeus is more correct, the init method is a better place to initalise the manAndDog.
Hope you don't mind some feedback ;)
You should be calling super.paint(g) in your paint method. In fact, I'd encourage you to use JApplet and override paintComponent, but that's just me
I don't see the need to continuously recreate the manAndDog object.
For example. If you added a method setLocation, you could simply call 'setLocation` when the mouse is dragged.
public void mouseDragged(MouseEvent e) {
dog.setLocation(xposR, yposR);
xposR = e.getX();
yposR = e.getY();
repaint();
}
This is more efficient as it's not continuously creating short lived objects. It also means you can do more with the manAndDog object, such as apply animation. IMHO

The simplest way is to create the ManAndDog object in your init() method, something like:
dog = new ManAndDog(0, 0);

Related

Move object in simple Java BigBang World

I am attempting to create a Big Bang world which contains a circle whose initial state should have it moving one pixel diagonally to the bottom-right. Every time the user presses the four arrow keys, the circle should move one pixel towards that direction and keep moving. For example, if I keep pressing the right arrow key, the circle should move towards the right and keep moving faster and faster each time I press it. The problem I am having is that I can't get the circle to move at all! I thought changing x and y coordinates oft he circle for each method should move it accordingly. What am I doing wrong? What can I do to have the circle move as I have described it? Here is the file Game.java that I need to fix:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Game implements World {
public Game() { }
int x, y = 200;
int width, height = 100;
void Circle(int x, int y, int width, int height){
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public void draw(Graphics g) {
int x = 200;
int y = 200;
int width = 100;
int height = 100;
g.setColor(Color.red);
g.fillOval(x,
y,
width,
height);
}
public void teh() {
this.x++;
this.y++;
}
public void meh(MouseEvent e) {
int x = e.getX(), y = e.getY();
System.out.println("Mouse event detected.");
}
public void keh(KeyEvent e) {
int x = e.getKeyLocation(), y = e.getKeyLocation();
int key = e.getKeyCode();
if (key == KeyEvent.VK_UP){
this.y--;
System.out.println("Up.");
}
else if (key == KeyEvent.VK_DOWN){
this.y++;
System.out.println("Down.");
}
else if (key == KeyEvent.VK_RIGHT){
this.x++;
System.out.println("Right.");
}
else if (key == KeyEvent.VK_LEFT){
this.x--;
System.out.println("Left.");
}
else{}
// switch( keyCode ) {
// case KeyEvent.VK_UP:
// // handle up
// break;
// case KeyEvent.VK_DOWN:
// // handle down
// break;
// case KeyEvent.VK_LEFT:
// // handle left
// break;
// case KeyEvent.VK_RIGHT :
// // handle right
// break;
// }
}
public boolean hasEnded() {
return false;
}
public void sayBye() {
System.out.println("BYE!");
}
public static void main(String[] args) {
BigBang b = new BigBang(new Game());
b.start( 50, // delay
400 // size
);
}
}
These are the supplementary files that are used but should remain untouched. I am including them for your reference:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class BigBang extends JComponent implements ActionListener, MouseListener, MouseMotionListener, KeyListener {
Timer timer;
World world;
public BigBang(World world) {
this.world = world;
this.addMouseListener(this);
this.addMouseMotionListener(this);
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocus();
}
public void start(int delay, int size) {
JFrame a = new JFrame();
a.add( this );
a.setVisible(true);
a.setSize(size, size);
this.timer = new Timer(delay, this);
this.timer.start();
}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) {
this.world.meh(e);
this.repaint();
}
public void mouseDragged(MouseEvent e) {
this.world.meh(e);
this.repaint();
}
public void mouseMoved(MouseEvent e) { }
public void mouseReleased(MouseEvent u) {
this.world.meh(u);
this.repaint();
}
public void mouseClicked(MouseEvent e) { }
public void keyPressed(KeyEvent e) {
this.world.keh(e);
this.repaint();
}
public void keyReleased(KeyEvent e) { }
public void keyTyped(KeyEvent e) { }
// int count;
public void actionPerformed(ActionEvent e) {
// this.count += 1;
// System.out.println("Ouch" + this.count);
if (this.world.hasEnded()) {
this.timer.stop();
this.world.sayBye();
} else {
this.world.teh();
}
this.repaint();
}
public void paintComponent(Graphics g) {
this.world.draw(g);
}
}
And the interface World.java:
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
interface World {
void draw(Graphics g);
void teh();
void meh(MouseEvent e);
void keh(KeyEvent e);
boolean hasEnded();
void sayBye();
}
Where does my mistake lie? Why am I not able to move the circle when the arrow keys are pressed? How can I continue to add on to the velocity of the object each time the arrow key is pressed? Any modifications or advice will be helpful.
The issue is in your draw method:
public void draw(Graphics g)
{
int x = 200;
int y = 200;
int width = 100;
int height = 100;
g.setColor(Color.red);
g.fillOval(x, y, width, height);
}
You are constantly making new local variables, x, y, width, and height, and drawing with those
Instead you should be using the variables your class already has designed:
public void draw(Graphics g)
{
g.setColor(Color.red);
g.fillOval(x, y, width, height);
}

ReboundPanel Inheritance

The happy face Im using----)This project wants me to Modify the Rebound program from this chapter such that when the mouse button is clicked the animation stops, and when its clicked again the animation resumes.
When I click on the screen with the moving smiley face, it doesnt stop when I click it nor start up again because I couldnt stop the smiley face from moving What am I doing wrong? Here is the problem area.------) |
private class ReboundMouseListener implements MouseListener {
public void mouseClicked(MouseEvent event) {
if (timer.isRunning())
timer.stop();
else
timer.start();
}
}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mousePressed(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
}
Here is the rest of the code:
public class ReboundPanel extends JPanel {
private final int WIDTH =300, HEIGHT= 100;
private final int DELAY= 20, IMAGE_SIZE=35;
private ImageIcon image;
private Timer timer;
private int x, y, moveX, moveY;
//---------------------------------------------------------
// Sets up the panel,including the timer for the animation.
//---------------------------------------------------------
public ReboundPanel(){
timer= new Timer(DELAY, new ReboundListener());
image= new ImageIcon("happyFace.gif");
x=0;
y=40;
moveX=moveY=3;
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.black);
timer.start();
}
//---------------------------------------------------------
// Draws the image in the current location.
//---------------------------------------------------------
public void paintComponent(Graphics page)
{
super.paintComponent(page);
image.paintIcon(this, page, x, y);
}
//*********************************************************
// Represents the action listener for the timer.
//*********************************************************
private class ReboundListener implements ActionListener
{
//--------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------
public void actionPerformed(ActionEvent event)
{
x += moveX;
y += moveY;
if (x <=0 || x >= WIDTH-IMAGE_SIZE)
moveX =moveX * -1;
if (y <=0 || y >= HEIGHT-IMAGE_SIZE)
moveY = moveY * -1;
repaint();
}
}
private class ReboundMouseListener implements MouseListener {
//--------------------------------------------------------------
// Stops or starts the timer (and therefore the animation)
// when the mouse button is clicked.
//--------------------------------------------------------------
public void mouseClicked(MouseEvent event) {
if (timer.isRunning())
timer.stop();
else
timer.start();
}
//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
public void mousePressed(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
}
}
public class Rebound {
public static void main(String[] args) {
JFrame frame = new JFrame("Rebound");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ReboundPanel());
frame.pack();
frame.setVisible(true);
}
}
Looks like you are missing your addMouseListener() calls:
public ReboundPanel() {
// Other initializations ...
addMouseListener(new ReboundMouseListener()); // <-- add
timer.start();
}

Making the getX() and getY() methods to get the locations of the panel, not the frame

I'm using the getX() and getY() methods in the MouseListener class to get the location of the panel, but it's getting the location of the frame instead, and that includes the top of the title bar and the sides, so it's not getting the location that I want. I also have the:
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
method in my paint class to override the frame so when you paint in graphics, and set the paint location of x, and y, it sets it to the panel location, and not the frame location, but I don't know how to make it so that the MouseListener class does the same. Please help. Thanks.
Code for the MouseListener class:
package events;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Events implements ActionListener, MouseListener, MouseMotionListener {
static Events events = new Events();
int x;
int y;
public void actionPerformed(ActionEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
System.out.println("X:" + x + " " + "Y:" + y);
}
public void mouseMoved(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
}
}
Nevermind. I can just call the panel name for the panel x, and y locations. But thanks anyways.
x = P.g.getX();
y = P.g.getY()

can't draw on a JPanel after repaint method

I'm experimenting on a GUI that I programmed and I don't understand how I can fix my problem:
My GUI contains a jPanel that on receiving a mouseclick, paints a point with filloval command.
private void myPnlMousePressed(java.awt.event.MouseEvent evt) {
changed = true;
p.x = evt.getX();
p.y = evt.getY();
drewPoints(p.x, p.y);
}
private void drewPoints (int x, int y) {
if (gf == null) {
gf = (Graphics)myPnl.getGraphics();
}
myPointsList.add(new Point(x, y));
gf.fillOval(x, y, 5, 5);
xVal.setText("X = " + x);
yVal.setText("Y = " + y);
}
everything works fine but when I want to open an XML file that I created to save all the points it doesn't work.
The problem is that when I use the repaint method on the jPanel after choosing a file, all the points loads fine but the panel can't draw the points.
If I put the repaint method in the open button listener (before the choosing file) it works, but then if the user cancels the open option so the panel stays blank and I don't want to draw the points again.
I think it happens because the repaint process is not finished.
All the points added to a private List.
private void OpenFile() {
try {
File thisFile;
JFileChooser of = new JFileChooser();
int option = of.showOpenDialog(of);
if (option == JFileChooser.APPROVE_OPTION){
thisFileName = of.getSelectedFile().getPath();
thisFile = new File(thisFileName);
if (!of.getSelectedFile().getName().endsWith(".xml")) {
String error = "Error, You didn't select XML file";
JOptionPane.showMessageDialog(this, error, "Wrong type of file", JOptionPane.INFORMATION_MESSAGE);
return;
}
myPnl.repaint();
myPointsList.clear();
....
....
....
for (int i = 0; i < pointsList.getLength(); i++) {
Element point = (Element) pointsList.item(i);
p.x = Integer.parseInt(point.getElementsByTagName("X").item(0).getTextContent());
p.y = Integer.parseInt(point.getElementsByTagName("Y").item(0).getTextContent());
drewPoints(p.x, p.y);
}
....
how can I make it work??
Don't use gf = (Graphics)myPnl.getGraphics();, this is not how painting in Swing works. The getGraphics method can return null and is nothing more then a snap shot of the last paint cycle, any thing you paint to it will be erased on the next paint cycle (repaint).
Instead, override the JPanels paintComponent and put all you painting logic there. There is an expectation that when called, you are expected to fully re-paint the current state of the component.
See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing
You have to use the repaint() and override the paint() method:
class MyPanel extends JPanel implements MouseListener
{
private int x;
private int y;
public MyPanel() {
super();
addMouseListener(this);
}
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mousePressed(MouseEvent e) { }
#Override public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 10, 10);
}
}
If you want to draw all points, don't use x and y but a list of points:
class MyPanel extends JPanel implements MouseListener
{
private ArrayList<Point> points = new ArrayList<>();
public MyPanel() {
super();
addMouseListener(this);
}
#Override public void mouseEntered(MouseEvent e) { }
#Override public void mouseExited(MouseEvent e) { }
#Override public void mouseClicked(MouseEvent e) { }
#Override public void mousePressed(MouseEvent e) { }
#Override public void mouseReleased(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
#Override public void paint(Graphics g) {
super.paint(g);
for (Point p : points)
g.fillOval(p.getX(), p.getY(), 10, 10);
}
}
where:
class Point
{
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Then use it:
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
MyPanel myPanel = new MyPanel();
frame.add(myPanel);
frame.setVisible(true);
}

Java mouseevent error - "method already defined in class"

I am trying to implement a click and drag method, for which I need mousePressed and mouseReleased events. I will also be using mouseClicked events, so I implemented MouseMotionListener and MouseListener.
However, when I go to write mousePressed, mouseReleased, mouseEntered, mouseExited methods I get the following error:
method mousePressed(MouseEvent) is already defined in class BoingPanel
Here is the entire class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import javax.swing.JPanel;
public class BoingPanel extends JPanel implements MouseMotionListener, MouseListener {
private int width;
private int height;
private int updateRate=40;
ArrayList<Ball> balls;
ArrayList<Line> lines;
private Container box;
private boolean drag = false;
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
public BoingPanel()
{
balls = new ArrayList<Ball>();
balls.add(new Ball(100,0)); // adds test ball
balls.get(0).setXVelocity(5);
balls.add(new Ball(100,0));
balls.add(new Ball(400,50));
lines = new ArrayList<Line>();
lines.add(new Line(0, height, width, height));
gameStart();
}
public BoingPanel(int x, int y)
{
width=x;
height=y;
balls = new ArrayList<Ball>();
balls.add(new Ball(100,0)); // adds test ball
balls.get(0).setXVelocity(5);
balls.add(new Ball(100,0));
balls.add(new Ball(400,50));
lines = new ArrayList<Line>();
box = new Container(width, height);
gameStart();
}
#Override
public void mouseDragged(MouseEvent me) {
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
public void gameStart() {
// Run the game logic in its own thread.
Thread gameThread = new Thread() {
public void run() {
while (true) {
// Execute one time-step for the game
update();
// Refresh the display
repaint();
// Delay and give other thread a chance
try {
Thread.sleep(1000 /updateRate);
} catch (InterruptedException ex) {}
}
}
};
gameThread.start(); // Invoke GaemThread.run()
}
private void update()
{
for(Ball a:balls) //calls balls updated position
{
a.update(box);
}
}
public void paintComponent(Graphics g)
{
box.paint(g);
for(Ball a:balls) //calls balls updated position
{
a.paint(g);
}
for(Line b:lines) //draws lines
{
b.paint(g);
}
}
public void actionPerformed(ActionEvent e)
{
update(); //changes ball position
repaint(); //refreshes image
}
}
What is causing this error? Thanks!
I would suggest this, just below your variable declarations and before you constructor, isn't helping...
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
You've basically implemented these methods twice. Just before and after the constructor.
Simply remove on of these groups of declarations...
please remove public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { } and then try

Categories

Resources