KeyListener being temporarily blocked out...?

Hi

I am writing a program that involves the following skeletal structure: The constructor initializes the main panel, which contains a Canvas, to which I've attached a KeyListener. Then, in another panel there is a button that starts a ``Thread'' (a while loop that keeps repeating with a delay between iterations) controlling stuff on the Canvas. However, when I press the button and the ActionEvent is processed, starting the thread, the KeyEvents are no longer processed (that is, my keyPressed function is not called) until the thread stops, when all the keys I pressed while the ``thread'' was running get processed all at once. However, I would like for the program to respond to keystrokes while the thread is running.

I'll provide more details if necessary, but are there any ideas what I might be doing wrong? Thanks.

[852 byte] By [xplodesa] at [2007-10-2 19:50:30]
# 1
you are doing a wait in your thread that is not yeilding?change it to sleep.
morgalra at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...
# 2
and/or come up with logic that explicitely yeilds while you wait.
morgalra at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...
# 3
Seems like you may be using the AWT thread to run your loop rather than creating another thread. Can you post your code where you create the new thread?
tjacobs01a at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...
# 4

A skeleton of the code is:

public class myClass extends Canvas implements ActionListener, MouseListener, KeyListener

//Stuff omitted

private boolean going = false;

public myClass() //Constructor

{

//...

JButton startButton = new JButton("Start!");

startButton.setActionCommand("Start");

startButton.addActionListener(this);

this.addKeyListener(this);

this.addMouseListener(this);

}

public void paint(Graphics g)

{

//Paint stuff

}

public void mainLoop()

{

while(going)

{

updateObjects();

repaint();

try

{

Thread.sleep(speed); //speed is the delay time and has been adjusted to no effect on the problem

}

catch(Exception exc)

{

exc.printStackTrace(System.out);

}

}

}

public void keyPressed(KeyEvent e)

{

System.out.println("KeyPress");

//Do other stuff

}

public void actionPerformed(ActionEvent e)

{

if(e.getActionCommand().equals("Start"))

{

going = true;

requestFocus();

mainLoop();

}

}

//Other functions as required by the implementation of the interfaces

Then, if I press the start button, the loop goes OK, but if I press keys while going = true, (i.e. while mainLoop() is running) the computer does not respond to them until after mainLoop() stops running, when it responds to them all at once (so for example, if I press start and then press 10 keys while it is going, the moment it stops, it prints out ``KeyPress'' 10 times). I tried modifying this so that instead of running a while loop, it created a new thread that repeatedly called a step function that was analogous to a single iteration of the loop in mainLoop(). Nothing changed, though.

Edit: Another common problem that wasn't the problem here is that the Canvas with the KeyListener did have the focus--I clicked like mad on it while the Thread was running and it still wouldn't respond until the Thread stopped.

xplodesa at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...
# 5

That code doesnt start another "thread".

Try this:

public class myClass extends Canvas implements ActionListener, MouseListener, KeyListener, Runnable

{

//Stuff omitted

private boolean going = false;

public myClass() //Constructor

{

//...

Thread.start(this); // Starts the thread, but doesnt do anything until going is equal to True

JButton startButton = new JButton("Start!");

startButton.setActionCommand("Start");

startButton.addActionListener(this);

this.addKeyListener(this);

this.addMouseListener(this);

}

public void paint(Graphics g)

{

//Paint stuff

}

public void run() // Changed this to runnable so it can be its own thread

{

while(true)

{

if(going) {

updateObjects();

repaint();

}

try

{

Thread.sleep(speed);

} catch (Exception exc) {

exc.printStackTrace(System.out);

}

}

}

public void keyPressed(KeyEvent e)

{

System.out.println("KeyPress");

//Do other stuff

}

public void actionPerformed(ActionEvent e)

{

if(e.getActionCommand().equals("Start"))

{

going = true;

requestFocus();

mainLoop();

}

}

//Other functions as required by the implementation of the interfaces

This makes the method run() its own thread, so you key actions will work.

Futurisdom_Developera at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...
# 6
Futurisdom_Developer, Wow, that worked perfectly. Thank you!
xplodesa at 2007-7-13 22:29:27 > top of Java-index,Other Topics,Java Game Development...