Edit: a user marked that my question is a possible duplicate of this question: "What is the volatile keyword useful for", whose title is "What is the volatile keyword useful for?". I read the question but I don't see how it relates to my question.
Here is a program written in two .java files. My question involves the if..else.. in the main method.
Note in the code below, the single line within the else {..} is commented out. I'll call this "version 1" of the program, and I'll call the program with that line commented back in "version 2".
// -------------
// The code below is in IfElseBugProgram.java
public class IfElseBugProgram {
public static void main(String[] args) {
MyJFrame terminal = new MyJFrame();
while (true) {
String keyReleased = terminal.getKeyReleased();
if (! keyReleased.equals("") )
{
System.out.print("@" + keyReleased);
}
else
{
// System.out.print("!" + keyReleased);
}
}
}
}
// -----
//The code below is in file MyJFrame.java
import javax.swing.JFrame;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
public class MyJFrame extends JFrame implements KeyListener
{
private List<KeyEvent> keyEventQueue;
public MyJFrame()
{
keyEventQueue = new ArrayList<KeyEvent>();
this.addKeyListener(this);
pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public void keyPressed(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent keyEvent)
{
keyEventQueue.add(keyEvent);
System.out.println("some key was released!" + keyEventQueue.size());
}
public String getKeyReleased()
{
int i = keyEventQueue.size();
if (i == 0)
{
return ("");
}
else
{
return ("" + i);
}
}
}
I expect that the code in the if {...} to be run, once I press a key on my keyboard. That is, I expect the
System.out.print("@" + keyReleased);
code to be run as soon as I press a key.
With version 1, I never seem to get System.out.print("@" + keyReleased);
to be run; there are never "@1" or "@2" or "@3"s etc printed in the console.
With version 2 (that is, with the code in the else {..} block commented back in),
- what USUALLY happens is that the print statement that prints out "!" gets run repeatedly, until I press a key. At that point, things like "@1" or "@2" etc get repeatedly printed.
- what SOMETIMES happens is that I get no "!" nor "@1" or "@2" printed out! (With the same source code!)
Question: Why does the System.out.print("@" + keyReleased);
line in the if {..} block not run in version 1, but (usually) does in version 2?
Additional Observations:
The print statement
System.out.println("some key was released!" + keyEventQueue.size());
in MyJFrame#keyReleased() always prints out, no matter how I change the code.I thought that perhaps something might be wrong with my console in Netbeans. But I tried running other code in the if {..} block, such as the line of code
java.awt.Toolkit.getDefaultToolkit().beep();
, which makes a sound. I also tried making some graphics display in the JFrame itself. The result is the same: with the line of code in the else {...} commented out, the code in the if {..} block doesn't seem to run; but if I comment the line of code in the else {..} back in, the code in the if {...} block (including making a sound or displaying something in the JFrame) does in fact run.I'm pretty sure that the condition of the if,
if (! keyReleased.equals("") )
is correct. I tried adding the one line of codeSystem.out.println("?" + (! keyReleased.equals("")) );
just above theif (! keyReleased.equals("") )
, and consistently on my console I would get "?false" printed repeatedly, until I pressed a key, at which point I got "?true" printed repeatedly.
But also: weirdly, putting in this one line of code(System.out.println("?" + (! keyReleased.equals("")) );)
above theif
in version 1 causes the lines of code in the if {..} block to now run?!
(optional) Background:
This section explains the code I am ultimately trying to write. If you wish to suggest an approach that might get me to this goal, that is different than the approach I'm using above, please feel free to suggest it.
I am trying to build a simple class called MyJFrame which can help motivate a friend learn how to program. The idea is to allow him to learn about variables in a visually motivated way, by programming extremely simple games, just like I learned when learning BASIC as a child. I want him to be able to write a program, completely contained in one main() method; I want him to have a simple way to draw a string on the screen, and a simple way to get user input. An example program might look like this:
int playerLocationX = 3;
int playerLocationY = 4;
MyJFrame terminal = new MyJFrame();
while(true)
{
// erase player that was drawn during the previous iteration of this loop
terminal.write(" ", playerLocationX, playerLocationY);
// get a key the user last pressed (if the user pressed a key) and update
// player location
String keyReleased = terminal.getKeyReleased();
if (keyReleased.equals("LEFT"))
{
playerLocationX = playerLocationX - 1;
}
else if (keyReleased.equals("RIGHT"))
{
playerLocationY = playerLocationY + 1;
}
// draw player again, using most recent player location
terminal.write("@", playerLocationX, playerLocationY);
}
I don't want to have him need to write his own keyReleased() method (ie, implementing a KeyListener interface), because this requires knowledge of writing your own methods; it also requires knowledge of objects, because a keyReleased() method has no way of modifying the local variables playerLocationX and playerLocationY stored in main().