Java; Jframe not repainting - java

I'm trying to create a circle around the mouse constantly in a JFrame, i.e the circle follows the mouse around the screen. To do this, I'm trying to use repaint() coupled with a timer, so that the circle continuously updates its location. For now, I have the program repainting the circle every second.
class MouseJFrame extends JFrame implements MouseListener{
int circleXcenter;
int circleYcenter;
int circleRadius = 25;
boolean show = false;
int delay = 1000;
// listen for and respond to mouse events
public MouseJFrame(){
new Timer(delay, taskPerformer).start();
addMouseListener(this);
}
// paints a circle
public void paint(Graphics g){
super.paint(g);
if(show){
g.drawOval(circleXcenter,circleYcenter,
circleRadius*2,circleRadius*2);
}
}
// getX and getY return the location of the mouse
ActionListener taskPerformer = new ActionListener() {
public void mouseDragged(MouseEvent e){
int xLocation = e.getX();
int yLocation = e.getY();
show = true;
circleXcenter = xLocation-circleRadius;
circleYcenter = yLocation-circleRadius;
repaint();
}
public void mouseMoved(MouseEvent e){
int xLocation = e.getX();
int yLocation = e.getY();
show = true;
circleXcenter = xLocation-circleRadius;
circleYcenter = yLocation-circleRadius;
repaint();
}
};
// class to create MouseJFrame object
public class TestMouseJFrame{
public static void main(String[] a){
MouseJFrame myMouseJFrame = new MouseJFrame ();
myMouseJFrame.setSize(200, 200);
myMouseJFrame.setVisible(true);
}
}
However, I get an error message regarding the ActionListener. When I try to fix this I get a load of other errors.
What can I do to get my program to run as intended?

Related

Cannot get mouse position in Java

Paint class:
public class Paint extends JPanel implements ActionListener {
Image swimmingpool;
Mouse swim = new Mouse();
Timer tm = new Timer(7, this);
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(swim.getdistance()); //prints out 0 ?!?
ImageIcon swimminghold = new ImageIcon(render.class.getResource("resources/Swimmingpoolns.png"));
swimmingpool = swimminghold.getImage();
g.drawImage(swimmingpool, 0,-40,null);
if (swim.getdistance() >= 3) {
System.out.println("test works");
}
}
public void actionPerformed(ActionEvent e) {
repaint();
}
}
Mouse class
public class Mouse implements MouseMotionListener {
private int x1 = 200;
private int y1 = 165;
double distance;
public void mouseMoved(MouseEvent e) {
double distance1 = Math.pow((e.getX() - x1), 2);
double distance2 = Math.pow((e.getY() - y1), 2);
setdistance(Math.sqrt(distance1 + distance2));
// The below prints, and has been
// tested to print the correct distance
System.out.println(getdistance());
}
public void setdistance(double distance) {
this.distance = distance;
}
public double getdistance() {
return distance;
}
}
When I execute System.out.println(getdistance()) in the Mouse class it prints the correct distance whereas if I execute System.out.println(swim.getdistance()); in the paint class prints 0.
Everything I've tried to do still results in distance = 0, in the class public void paintComponent(Graphics g).
What am I not understanding?
As pointed out by #Hunter-mcmillen: you are confused about java operators.
public void mouseMoved(MouseEvent e) {
double distance1 = Math.pow((e.getX() - x1),2);
double distance2 = Math.pow((e.getY() - y1),2); // Math.pow(a,b) == a^b (in a calculator)
setdistance(Math.sqrt(distance1 + distance2));
System.out.println(getdistance());
}
I really recommend that you read more carefully the Java operators before assuming how they work on the language.
EDIT 2:
I recommend also that you create a JPanel or JLabel for this picture, and then load such picture inside this new Jpanel or Label or other component.
public class Paint extends JPanel implements ActionListener {
Mouse swim = new Mouse();
Timer tm = new Timer(7, this);
public void paintComponent(Graphics g) {
// Try this:
ImageIcon swimminghold = new ImageIcon(render.class.getResource("resources/Swimmingpoolns.png"));
swimmingpool = swimminghold.getImage();
JLabel label = new JLabel();
label.setIcon(swimminghold);
label.addMouseMotionListener(swim);
addMouseMotionListener(swim);
label.addMouseMotionListener(swim);
addMouseMotionListener(swim);
//Do something
/* ...*/
}

Java MouseMotionListener and restricting drawn shapes movement

Working on an applet that draws 2 eyes and uses MouseMotionListener to move the they eyes. Also when the mouse exits the content pane, the eyes look straight. The one thing
I'm struggling with is I can't figure out how to restrict the pupils movements to stay within the eye. Any suggestions you guys have would be great.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WatchMe extends JApplet
{
private int leftMouseX = 130;
private int leftMouseY = 155;
private int rightMouseX = 305;
private int rightMouseY = 155;
private boolean mouseEntered;
//init method
public void init()
{
//set background to green
getContentPane().setBackground(Color.green);
//add mouse listener
addMouseListener(new MyMouseListener());
//add a motion listener
addMouseMotionListener(new MyMouseMotionListener());
}
public void paint(Graphics g)
{
//call superclass paint method
super.paint(g);
//draw left eye
g.setColor(Color.yellow);
g.fillOval(75, 100, 150, 150);
//draw left pupil
g.setColor(Color.black);
g.fillOval(leftMouseX, leftMouseY, 40, 40);
//draw right eye
g.setColor(Color.yellow);
g.fillOval(250, 100, 150, 150);
//draw right pupil
g.setColor(Color.black);
g.fillOval(rightMouseX, rightMouseY, 40, 40);
//checks to see if the mouse is in the pane, if not
//sets the x,y coordinates to look straight
if (! mouseEntered)
{
leftMouseX = 130;
leftMouseY = 155;
rightMouseX = 305;
rightMouseY = 155;
repaint();
}
}
private class MyMouseListener implements MouseListener
{
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
mouseEntered = true;
repaint();
}
public void mouseExited(MouseEvent e)
{
mouseEntered = false;
repaint();
}
}
private class MyMouseMotionListener implements MouseMotionListener
{
public void mouseDragged(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e)
{
leftMouseX = e.getX();
leftMouseY = e.getY();
rightMouseX = e.getX();
rightMouseY = e.getY();
repaint();
}
}
}
As a start I would recommend putting your eye dimensions in variables as shown below. This way you reduce the chance of errors when entering the same numbers more than once, and if you later decide to change the eye size or position, you only have to change it once.
public static final int LEFT_X = 75;
public static final int LEFT_Y = 100;
public static final int EYE_SIZE = 150;
We also need the left pupil to be independent of the mouse (so it doesn't follow the mouse out of the eye) so we'll do this:
private leftPupilX = 130;
private leftPupilY = 155;
Next you need to determine whether or not the mouse is currently in the left eye. This is what will restrict the pupil to the bounds of the eye. I've done this in a method for convenience.
public void setLeftEye() {
//Set the X Coord for the pupil
//Mouse is to the left of the eye
if(leftMouseX < LEFT_X) {
leftPupilX = LEFT_X;
//Mouse is to the right of the eye
} else if(leftMouseX > LEFT_X + EYE_SIZE) {
leftPupilX = LEFT_X + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilX = leftMouseX;
}
//Set the Y Coord for the pupil
//Mouse is above the eye
if(leftMouseY < LEFT_Y) {
leftPupilY = LEFT_X;
//Mouse is below the eye
} else if(leftMouseY > LEFT_Y + EYE_SIZE) {
leftPupilY = LEFT_Y + EYE_SIZE;
//Mouse is in eye
} else {
leftPupilY = leftMouseY;
}
}
Finally you'll need to update the code that draws the left pupil to reflect the variable change, and actually call our new method.
//draw left pupil
setLeftEye();
g.setColor(Color.black);
g.fillOval(leftPupilX, leftPupilY, 40, 40);
These changes should make the left eye track your mouse the way you described. You'll need to do something similar for the right eye, since it has different coordinates. If you have any problems, let me know and I will try to help. :)

How to add mouselistener on random drawn image in java?

I am building a game in Java and I need to add a mouselistener to an random drawn image in my game.
I made the image appear on random places every x seconds, when I click the image I would like to add 1 point to the scoreboard.
My code for the random image adding is:
Random rand = new Random();
private int x = 0;
private int y = 0;
Timer timer = new Timer(700, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
x = rand.nextInt(400);
y = rand.nextInt(330);
repaint();
}
});
public void mousePressed (MouseEvent me) {
// Do something here
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(achtergrond, 0, 0, this.getWidth(), this.getHeight(), null);
//g.drawImage(muisje, 10, 10, null);
g.drawImage(muisje, x, y, 100, 100, this);
}
I looked on google and found that I need to add a new class with a mouse event, but How do I add this? It's not clear enough because I'm just a beginner in Java.
You know where the image is drawn (x,y) and you know the size of the image (100,100), therefore to tell if the mouse click is inside the image you can do something like this:
public void mousePressed (MouseEvent me) {
int clickX = me.getXOnScreen();
int clickY = me.getYOnScreen();
if(clickX > x && clickX < x+100 && clickY > y && clickY < y+100) {
//the image has been clicked
}
repaint();
}
The class you're writing can then implement MouseListener.
EDIT in response to comment:
You don't need to link the code to the image, the component that you're writing should implement the mouse listener since this maintains the state and knows where the image is drawn. I would start out by looking at this link and implementing a basic MouseListener to print out the x and y co-ordinates of mouse clicks on your component:
http://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
Example component implementing Mouse Listener:
public class TestComponent extends JComponent implements MouseListener {
public TestComponent() {
this.addMouseListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
int clickedX = e.getX();
int clickedY = e.getY();
System.out.println("User Clicked: " + clickedX + ", " + clickedY);
}
#Override
public void mousePressed(MouseEvent e) {}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
}
You need to register a MouseListener for your Gamevenster class. Instead of making the class implement MouseListener, just use a MouseAdapter, where you only have to implement the method mouseClicked. So in your constructor, you something like this
private JLabel scoreLabel = new JLabel("Score: " + score);
private int score = 0;
public Gamevenster() {
scoreLabel.setFont(new Font("impact", Font.PLAIN, 30));
scoreLabel.setForeground(Color.WHITE);
add(scoreLabel);
addMouseListener(new MouseAdapter(){
#Override
public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int clickX = (int)p.getX();
int clickY = (int)p.getY();
if(clickX > x && clickX < x + 100 && clickY > y && clickY < y + 100) {
score++;
scoreLabel.setText("Score: " + score);
}
}
});
}

Stop pause on key hold with KeyBindings Java

I'm trying to write a Pong applet in Java. When the user holds down either up or down, their paddle should move smoothly, but this isn't the case. It moves, then pauses, then starts moving again. Is there a way to stop this short pause from happening?
Main Class:
public class Main extends JApplet {
public DrawPanel dp = new DrawPanel(400, 400);
public void init(){
add(dp);
setSize(400, 400);
requestFocusInWindow();
Action moveDown = new AbstractAction(){
public void actionPerformed(ActionEvent e){
dp.player.y += 10;
dp.repaint();
}
};
dp.getInputMap().put(KeyStroke.getKeyStroke("pressed DOWN"), "move down");
dp.getActionMap().put("move down", moveDown);
}
}
DrawPanel Class:
public class DrawPanel extends JPanel {
public Paddle player;
public Paddle opponent;
public DrawPanel(int height, int width){
int y = (height / 2) - (height / 10);
int w = 15;
int h = height / 5;
player = new Paddle(2, y, 15, h, Color.white);
opponent = new Paddle(width - (w+2), y, 15, h, Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(player.color);
g.fillRect(player.x, player.y, player.width, player.height);
g.setColor(opponent.color);
g.fillRect(opponent.x, opponent.y, opponent.width, opponent.height);
}
}
Paddle Class:
public class Paddle {
public int x, y, width, height;
public Color color;
public Paddle(int _x_, int _y_, int w, int h, Color c){
x = _x_;
y = _y_;
width = w;
height = h;
color = c;
}
}
The underlying issue is an impedance mismatch between the "instance" notion of a keyPressed and the "duration" notion of the movement.
Instead of trying to smooth that over in the view (which shouldn't have anything to do with the details of the game logic anyway), enhance the game model with api that's a better fit. F.i. add start/stop logic and bind those methods to keyPressed/keyReleased:
public class Paddle {
public void startMoveDown() {
// here goes the logic, f.i. starting a timer
// in the actionPerformed of that timer:
... moveUnitDown();
}
public void stopMoveDown() {
//...
}
protected void moveUnitDown() {
y+=unit;
// ideally, have listeners and notify them the change of y
}
}
// in the view:
Action startMoveDown = new AbstractAction(){
public void actionPerformed(ActionEvent e){
player.startMoveDown();
}
};
dp.getInputMap().put(KeyStroke.getKeyStroke("pressed DOWN"), "start move down");
dp.getActionMap().put("start move down", startMoveDown);
// in the view:
Action stopMoveDown = new AbstractAction(){
public void actionPerformed(ActionEvent e){
player.stopMoveDown();
}
};
dp.getInputMap().put(KeyStroke.getKeyStroke("released DOWN"), "stop move down");
dp.getActionMap().put("stop move down", stopMoveDown);

animation using repaint()

I am trying to create a simple animation which draws random rectangles when a button is pressed. So far I managed to create rectangle on the press of a button. I want to further develop the code so that when I press the button, more than multiple random rectangles are created. I tried to create a for loop which asks the inner class to repaint itself but it still didn't work. can anyone help me please.
public class TwoButtonsRandomRec {
JFrame frame;
private int width = 500;
private int height = 500;
private DrawPanel dp;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public static void main (String[] args)
{
TwoButtonsRandomRec test = new TwoButtonsRandomRec();
test.go();
}
public void go()
{
dp = new DrawPanel();
JButton start = new JButton("Start");
start.addActionListener(new startListener());
JButton stop = new JButton("Stop");
stop.addActionListener(new stopListener());
frame = new JFrame();
frame.setSize(getWidth(), getHeight());
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(BorderLayout.NORTH, start);
frame.getContentPane().add(BorderLayout.SOUTH, stop);
}
class startListener implements ActionListener{
public void actionPerformed(ActionEvent event){
frame.getContentPane().add(BorderLayout.CENTER, dp);
frame.repaint();
frame.getRootPane().revalidate();
for(int i=0; i<10; i++){
dp.repaint();
}
}
}
class stopListener implements ActionListener{
public void actionPerformed(ActionEvent event){
System.out.println("stop");
}
}
class DrawPanel extends JPanel{
public void paintComponent(Graphics g){
int w = 5+(int)(Math.random() * width-5);
int h = 5+(int)(Math.random() * height-5);
int maxX = width-w; // diffX & diffY are used to ensure that rectangle is
int maxY = width-h; // draw completely inside the window
int x = (int)(Math.random() * maxX);
int y = (int)(Math.random() * maxY);
Color color = new Color((int) (Math.random()*256), // random red
(int) (Math.random()*256), // random green
(int) (Math.random()*256));// random blue
g.setColor(color);
g.fillRect(x,y,w,h);
}
}
}
repaint() simply tells Swing "when you'll have time, please repaint this area". So if you add rectangles in a loop and call repaint at each iteration, all the rectangles will only appear after the loop has finished, and the action event has been handled.
To have an animation, you need to loop in a separate thread. The easiest way to do that is to use a Swing Timer. When the Start button is started, start a timer which adds a random rectangle and calls repaint() every X milliseconds. When the Stop button is pressed, stop the timer.
What you should do is to put the loop inside paintComponent method and not call repaint in the loop.
So your paintComponent method should look like this:
public void paintComponent(Graphics g){
for (int i = 0; i < 10; i++) {
int w = 5+(int)(Math.random() * width-5);
int h = 5+(int)(Math.random() * height-5);
int maxX = width-w; // diffX & diffY are used to ensure that rectangle is
int maxY = width-h; // draw completely inside the window
int x = (int)(Math.random() * maxX);
int y = (int)(Math.random() * maxY);
Color color = new Color((int) (Math.random()*256), // random red
(int) (Math.random()*256), // random green
(int) (Math.random()*256));// random blue
g.setColor(color);
g.fillRect(x,y,w,h);
}
}
And your action performed should look like this:
public void actionPerformed(ActionEvent event){
frame.getContentPane().add(BorderLayout.CENTER, dp);
frame.repaint();
frame.getRootPane().revalidate();
dp.repaint();
}
Well,here I have done a short EG for you.It displays random rectangles, random times on random screen location.
(You can set your own value of randomization, and the screen location max bound,as per your requirements.)
And also note
int i=(int)(Math.random()*10);
int j=(int)(Math.random()*10);
for(;i<j;i++)
Where at times i may be > than j.So,loop may not work on one or two cliks.Change as per your need.
Here is the working code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleStamper extends JApplet {
public void init() {
Display display = new Display();
setContentPane(display);
}
class Display extends JPanel implements MouseListener {
Display() {
setBackground(Color.black);
addMouseListener(this);
}
public void mousePressed(MouseEvent evt) {
if ( evt.isShiftDown() ) {
repaint();
return;
}
int x = evt.getX();
int y = evt.getY();
Graphics g = getGraphics();
//***MODIFY THE FOLLOWING LINES****//
int i=(int)(Math.random()*10);
int j=(int)(Math.random()*10);
for(;i<j;i++)
{ g.setColor(Color.red);
x=(int)(Math.random()*100);
y=(int)(Math.random()*100);
g.fillRect( x , y , 60, 30 );
g.setColor(Color.black);
g.drawRect(x , y , 60, 30 );}
g.dispose();
}
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseReleased(MouseEvent evt) { }
}
}

Categories