0

I've getInput method that takes string from text field on enter click. I've created while loop to wait until onClickListener returns true (pressed Enter). Here's my code:

public String getInput(){
    jTextField1.setEditable(true);
    jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
        public void keyPressed(java.awt.event.KeyEvent evt) {
            temp=jTextField1KeyPressed(evt);
        };
    });
    while(!(temp)){
    }
    temp=false;
    jTextField1.setEditable(false);
    String s= jTextField1.getText();
    jTextField1.setText("");
    return s;

}

private boolean jTextField1KeyPressed(KeyEvent evt) {
    if (evt.getKeyCode() == KeyEvent.VK_ENTER)
        return true;
    else return false;
};

Now I have very strange problem: if I add System.out.println sentence in while loop, it works perfectly, if I remove it, while loop never exits. Where is problem? Thanks in advance.

Mario
  • 335
  • 7
  • 20
  • I have no idea what you are attempting to do but your solution seems overly complicated. You should never create a "while loop" to wait for input. You should never use a KeyListener to listen for the enter key. You add an ActionListener to the text field for this purpose. Finally you title mentions a JTable. Well when you edit a cel in a table the editor automatically handles the closing of the editor when enter is used. You really need to describe your requirement because I'm sure a better solution is available. – camickr Mar 19 '11 at 15:58

3 Answers3

1

You would need some synchronization so that the changes to temp are propagated to all required threads. But it's a bad approach to start with - getInput will waste a lot of CPU looping in that while for no good purpose.

You could do it more cleanly. First, declare temp to be a java.lang.Object, and initialize it to a plain old Object:

private Object temp = new Object();

(or something like that.)

In getInput, instead of this:

while (!temp) { }
temp = false;

put this:

synchronized (temp) {
  try {
    temp.wait();
  } catch (InterruptedException ie) {
    // handle this situation: something interrupted your thread before input was finished
  }
}

And in the event handler:

synchronized (temp) {
  temp.notify();
}

This way, the thread running getInput stays asleep waiting for something to happen rather than burning CPU cycles.

There are also variants of wait() that take a timeout value. You might be interested in using those too.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • Your solution looks great, however I got crashes with NullPointerException. temp.wait() and temp.notify() give warnings Invoking Object.wait outside a synchronized context. What could be possibly wrong? – Mario Mar 19 '11 at 12:39
  • sorry, wasn't paying enough attention to what I was typing. I have edited my post. `temp` needs to be initialized once, either in the constructor or directly in its definition site in your class. BTW, `temp` is a _really bad_ variable name for anything but a very short lived, function-scoped temporary. – Mat Mar 19 '11 at 12:44
  • Thanks, everything works fine. For everybody else having same problem, you must also surround temp.notify() with synchronized as well. Cheers! – Mario Mar 19 '11 at 12:58
0

Your problem is called "busy waiting". You have to wait, until operating system tell you, that Enter was pressed. Asking a dummy question "Was Enter pressed?", "Was Enter pressed?", "Was Enter pressed?", "Was Enter pressed?", "Was Enter pressed?", "Was Enter pressed?", "Was Enter pressed?" 1000000000 times per second is not a good practice....

You may try to use this:

jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
    public void keyPressed(java.awt.event.KeyEvent evt) {
        temp=jTextField1KeyPressed(evt);
        if (temp==true) EnterPressed();
    };
});
void EnterPressed() {
    //enter code here
}
Artur Iwan
  • 1,151
  • 2
  • 10
  • 17
0

If you call your getInput from the event thread you will get stuck in an endless loop. The variable temp might never get updated because no events can be processed anymore.

If you want to gather a plain input you might want to look into a solution like

String info = JOptionPane.showInputDialog(this, "Please enter info");
Howard
  • 38,639
  • 9
  • 64
  • 83