Sign in to follow this  

[java] Mouse action in a while loop

This topic is 4056 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

public void paint( Graphics g )
{

super.paint(g);
g.drawImage( logo1.getImage(), x, y, null );
JLabel fk = new JLabel("hi");

//begin rnd
while (count > 1) {
    
    while ( i < 10000) { //change to control speed
    	i++;
    	System.out.println(i);
	Math.sqrt((double)i); // this should really chew up some time
    
    
    	if (i > 9999) {
    	i = i - 9999;
    		int xn = (int)(Math.random()*600);
     int yn = (int)(Math.random()*300);
     y = yn;
     x = xn;
   
 update(g);
  
}
Basicly can somebody show me how to make it so while in the while loop ( i <10000)i can add a action listener so when i click the image icon "logo1" it does a action. Thanks XD

Share this post


Link to post
Share on other sites
Quote:

JLabel fk = new JLabel("hi");


Is there some reason you are creating a JLabel each time paint(...) is called.


It sounds like you need to restructure your idea. However, you could create a queue of messages, and then check for messages each (or every N) itteration(s) through the while loop. Basicaly have your mouseListener.mouseClick event put the messages into an appropriate data structure (Vector/Linked List/Array etc...). Then check this data structure for messages.

Here is a psudo example

Vector messages

mouseClick(Event e)
messages.add(e)

paint()
while(n < 10000)
calculate()
if(messages.size() > 0)
processMessages()





It is possible to create a annonymous event handler inside this loop. But this is a VERRY BAD THING.


I am not sure exactly what you are trying to do, but it looks like you are updating the position of logo1 in the paint() method. Try doing this in it's own function, then call paint directly to draw the new position.

From your code it looks like you are calling the update(Graphics) function for your window within the paint method. I would recommend you do not do this. I can not tell how many recusions deep you get because I don't see the control logic for the count variable. If this never changed then as soon as paint is called, your program will continue to recurse into the paint method indifinitly... or until it dies with a stack overflow.

I suggest you abstract all your variable/graphics calculation routines away from your drawing routines.

Share this post


Link to post
Share on other sites
Your right i am trying to keep moving the ImageIcon acrooss the screen,I did what you said and made it sperate.
new code:
public void refresh() {
//begin rnd


while (count > 5) {
try {
Thread.sleep(SPEED);
} catch (InterruptedException e) {}


i++;
System.out.println(i);
Math.sqrt((double)i); // this should really chew up some time
//addMouseMotionListener(logo1);

int xn = (int)(Math.random()*600);
int yn = (int)(Math.random()*300);
y = yn;
x = xn;



//update(g); old
update(getGraphics());

}
}
Also I stoped using a while loop as a timer(sucked CPU XD)Thanks for the tip.
But know my application looks like it has chikenpox - because the ImageIcon is a red ball shape and it doesnt delete when it moves to a new pos but that should be a easy fix-.But im still not shure about makeing it so when you click the imageicon something happens

Share this post


Link to post
Share on other sites
It would be helpfull if you posted the entre class(s) to this thread. When you do please use source tags: souce and /source enclosed in []. I don't want to assume to much about your code, and lead you down the wrong path.

Personaly I would create a separate thread as the main 'render' loop. Alternatly you could run the animation on the main(...) thread. The event messaging will still be on another thread, so you will get your events.

I have to run to class right now. I'll post more details later.

Share this post


Link to post
Share on other sites
Thank i didnt want to post the whole class because i didnt want to waste anyones timer lol but i see why its important so here is the full source

/*
* Main.java
*
* Created on November 7, 2006, 8:55 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/


package imagetest;

import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import sun.audio.*;
import java.io.*;
//remember for snake game if snake = food x + y random pos of food +1score



public class Main extends JFrame {
int SPEED = 1000;
private ImageIcon logo1;//Defines logo1 as image icon
int delay = 5000; //5second delay
int period = 1000; //repeat every sec
public int x = 300;//defines x pos of logo1 later on
public int y = 300;//define y pos
int count = 500;
int score = 0;
int i = 0;
public Main()
{
JButton faris = new JButton("faris");
logo1 = new ImageIcon("ball.png");
getContentPane().setPreferredSize( new Dimension( 600, 300 ) );// sets screen to 600*300

pack();
setVisible( true );
setResizable(false); //stops user from resizing
setDefaultCloseOperation(EXIT_ON_CLOSE);
//audio code comin soon
//try {

// InputStream in = new FileInputStream("sound.mp3"); not work yet
// AudioStream as = new AudioStream(in);
// AudioPlayer.player.start(as);

//}
// catch(IOException e){
//System.out.println(e);
//}
//end audio code

}



public void paint( Graphics g )
{


g.drawImage( logo1.getImage(), x, y, null );


refresh();

}








public void refresh() {
//begin rnd


while (count > 5) {
try {
Thread.sleep(SPEED);
} catch (InterruptedException e) {}


i++;
System.out.println(i);
Math.sqrt((double)i); // this should really chew up some time
//addMouseMotionListener(logo1);

int xn = (int)(Math.random()*600);
int yn = (int)(Math.random()*300);
y = yn;
x = xn;



//update(g); old
update(getGraphics());

}
}


public static void main(String args[])
{
Main test = new Main();

}
}


Thanks:D

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Thank i didnt want to post the whole class because i didnt want to waste anyones timer lol but i see why its important so here is the full source

/*
* Main.java
*
* Created on November 7, 2006, 8:55 PM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/


package imagetest;

import javax.swing.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import sun.audio.*;
import java.io.*;
//remember for snake game if snake = food x + y random pos of food +1score



public class Main extends JFrame {
int SPEED = 1000;
private ImageIcon logo1;//Defines logo1 as image icon
int delay = 5000; //5second delay
int period = 1000; //repeat every sec
public int x = 300;//defines x pos of logo1 later on
public int y = 300;//define y pos
int count = 500;
int score = 0;
int i = 0;
public Main()
{
JButton faris = new JButton("faris");
logo1 = new ImageIcon("ball.png");
getContentPane().setPreferredSize( new Dimension( 600, 300 ) );// sets screen to 600*300

pack();
setVisible( true );
setResizable(false); //stops user from resizing
setDefaultCloseOperation(EXIT_ON_CLOSE);
//audio code comin soon
//try {

// InputStream in = new FileInputStream("sound.mp3"); not work yet
// AudioStream as = new AudioStream(in);
// AudioPlayer.player.start(as);

//}
// catch(IOException e){
//System.out.println(e);
//}
//end audio code

}



public void paint( Graphics g )
{


g.drawImage( logo1.getImage(), x, y, null );


refresh();

}








public void refresh() {
//begin rnd


while (count > 5) {
try {
Thread.sleep(SPEED);
} catch (InterruptedException e) {}


i++;
System.out.println(i);
Math.sqrt((double)i); // this should really chew up some time
//addMouseMotionListener(logo1);

int xn = (int)(Math.random()*600);
int yn = (int)(Math.random()*300);
y = yn;
x = xn;



//update(g); old
update(getGraphics());

}
}


public static void main(String args[])
{
Main test = new Main();

}
}


Thanks:D

Share this post


Link to post
Share on other sites
Thanks... I will take a look at it and post back. I have another class in an hour and need to get some dinner. I did write up a example to illistrate some of the things I was mentioning.

This class will rotate a box clockwize in the shape of a rounded edged box (uncomment the first fillRect in paint). It will stop the animation on a down click and resume it on a up click. This is a very quick hack, but it should suffice as an example.




import java.awt.* ;
import java.awt.event.* ;


public class GDNETJavaAnim extends Frame implements MouseListener, Runnable{

private Thread cls_Thread = null ;
private Rectangle cls_Rect = new Rectangle(10,10,50,50) ;

private boolean bool_Running = false ;
private boolean bool_StopThread = false ;

private boolean bool_StopAnim = false ;


public GDNETJavaAnim() {
super("GDNETJavaAnim") ;

//Setup window close event.
WindowAdapter wa = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0) ;
}
} ;

addWindowListener(wa) ;
addMouseListener(this) ;

setSize(320,240) ;
setVisible(true) ;


}

public void repaint() {
paint(getGraphics()) ;
}

public void update(Graphics g) {
paint(g) ;
}

public void paint(Graphics g) {
g.setColor(Color.white) ;
g.fillRect(0,0,getWidth(),getHeight()) ;
g.setColor(Color.black) ;
g.fillRect(cls_Rect.x,cls_Rect.y,cls_Rect.width,cls_Rect.height) ;
}

/**
* Start the animation
*/

public void start() {

try {
bool_StopThread = false ;
cls_Thread = new Thread(this) ;
cls_Thread.start() ;
}
catch(Exception e) {}
}

public void stop() {
bool_StopThread = true ;

while(bool_Running) {
try {Thread.sleep(100) ; }
catch(Exception e) {}
}
}

/*****************************************************************
* Interface Implementations
*****************************************************************/

/**
* Runnable Implementation
*/

public void run() {
bool_Running = true ;
double dx = 0, dy = 0 ;
double theta = 0 ;

try {
while(!bool_StopThread) {
if(!bool_StopAnim) {
theta = theta + .01d ;
dx = 50 * Math.cos(theta) ;
dy = 50 * Math.sin(theta) ;
cls_Rect.x = 100 + (int) dx ;
cls_Rect.y = 100 + (int) dy ;

paint(getGraphics()) ;
}

Thread.sleep(10) ;
}
}
catch(Exception e) {}
bool_Running = false ;
return ;
}

/**
* Mouse event handlers
*/


public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }

public void mousePressed(MouseEvent e) { bool_StopAnim = true ;}

public void mouseReleased(MouseEvent e) { bool_StopAnim = false ;}




public static void main(String args[]) {
new GDNETJavaAnim().start() ;
}

}



Share this post


Link to post
Share on other sites
The initial execution path through your program is as follows:

Main.main(...)- entry point
Main.Main - constructor
Main.paint() - Paint the image
Main.refresh() - Do some calculations and repaint

Here is the problem. You are using the paint() method to involk the refresh() function wich in turn involkes the paint() method ( via update(getGraphics()) ) and so on. These calls dont appear to unwind at any point. To make matters worse, the paint() method gets called by the Swing library. So now you have many calls into paint, which in turn call into refresh etc. Always control your execution flow using some predictiable behaviour. Using JFrame.paint() to start the execution of your applicaiton is not a good behaviour.

I also do not see where you are deincrementing the count variable, so the while loop in your refresh method runs forever. Maybe you are doing this just for testing.

In any case I recommend you do the following for now.

1. Remove the refresh function from your paint method. Only do rendering operations in here. Do not call any other functions that may call back into paint.

2. Remove the loops from your refresh function.

3. Create a loop in your constructor and call refresh from within this loop.

Essentialy this is what the example I wrote up for you does. You could easily move the looping in the run method to the bottom of the constructor and the program would work the same. The only difference is now you are running on the startup thread.

Basicaly you want the initialization and execution of your program to follow a path somewhat like this:

1. Initialize variables and resources
2. start main rendering loop
3. Calculate data
4. paint
5. goto 3


I hope some of this helps.

Share this post


Link to post
Share on other sites
Thanks for taking your spare time to help me i relly apprecaae it.
Ive learnt from your code and im going to rewrite my code make it more efficent,ill post back with my new code just incase you want to see it.The reson i wanted the while loop constant is so it kept randimazing a new position,so when you have to click the image as it moves around which adds up to your own score.Then ill make a multpayer version played from diffent computers.

Share this post


Link to post
Share on other sites

This topic is 4056 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this