Question

I have a program which is a mock inventory system with quite a few JTextField's and some regular expressions which some of those fields must comply with. Also, some fields cannot be null(obviously) or an empty String. In order to assist the user to input data, I've added some ImageIcon's to show if the input data is valid or invalid. (a green check or red x) and I setVisibility() as the user types via KeyEvents.

With that said, here is the confusion. I have a block which I'm pretty sure doesn't have a bug in it, but I've found that there's some odd things happening:

I'm only calling my updateIcons() method in response to keyTyped() - my overrides for the others are empty. Now, when a key is typed, the text is printed on the screen before the key is released, so you would think that an input field that simply requires at least one character to NEVER fail the validity check because if keyTyped() is the only entry point to my updateIcons() method, there should always be at least one character by the time the key is released and thus registered as a "key typed". However, it seems to be firing an event before the key even gets registered to the System. Something which makes this even more odd is if I call my updateIcons() method twice in a row from the overridden keyTyped() method, the program STILL fails the check for empty string. BUT if I call it for keyPressed(), keyReleased(), and keyTyped() all for the same event, presto; valid data. Could this possibly be caused by the instability/bugginess of AWT?

Here is the updateIcons() method in case it is something I overlooked, but since I'm getting such odd results I don't think its a bug on my end.

//called from keyTyped
//formInputIcons is a 2D array[8][2] where the first dimension represents
//the form input field, and the second dimension is the ImageIcons for that field
//public final Pattern upcRegex = Pattern.compile("^\\d{12}$");
//public final Pattern anyNumRegex = Pattern.compile("^\\d+$"); 

public void updateIcons(KeyEvent e){

    if(e.getSource() == formAddInputs[0]){
        formInputIcons[0][0].setVisible( ! (upcRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches()));
        formInputIcons[0][1].setVisible(upcRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches());

    }else if(e.getSource() == formAddInputs[1]){
        formInputIcons[1][0].setVisible(((JTextField)e.getSource()).getText().equals(""));
        formInputIcons[1][1].setVisible( ! ((JTextField)e.getSource()).getText().equals(""));

    }else if(e.getSource() == formAddInputs[3]){
        formInputIcons[3][0].setVisible(((JTextField)e.getSource()).getText().equals(""));
        formInputIcons[3][1].setVisible( ! ((JTextField)e.getSource()).getText().equals(""));


    }else if(e.getSource() == formAddInputs[4]){
        formInputIcons[4][0].setVisible(((JTextField)e.getSource()).getText().equals(""));
        formInputIcons[4][1].setVisible( ! ((JTextField)e.getSource()).getText().equals(""));


    }else if(e.getSource() == formAddInputs[6]){
        formInputIcons[6][0].setVisible( ! (anyNumRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches()));
        formInputIcons[6][1].setVisible(anyNumRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches());


    }else if(e.getSource() == formAddInputs[7]){
        formInputIcons[7][0].setVisible( ! (anyNumRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches()));
        formInputIcons[7][1].setVisible(anyNumRegex.matcher(
                ((JTextField)e.getSource()).getText()).matches());
     }
}

UPDATE: I'm an idiot - it works fine if I only call updateIcons() once from keyReleased() and leave keyPressed() and keyTyped() empty. I like to learn things though; could someone explain why keyTyped() is buggy in this usage but keyReleased() works fine or post a link please?

Was it helpful?

Solution

You need to be calling your update method from keyReleased(). I've made a simple JTextField which outputs the key and its getText() each time a key is pressed, and watch what happens:

keyPressed:c
text:
keyTyped:c
text:
keyReleased:c
text:c

keyPressed:a
text:c
keyTyped:a
text:c
keyReleased:a
text:ca

keyPressed:t
text:ca
keyTyped:t
text:ca
keyReleased:t
text:cat

You can see that the actual text of the JTextField is not updated by the keyTyped() or keyPressed() events.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top