0

I am creating a hangman game and I was having trouble getting the jlabel that contained each character of the word to update after the right letter button has been clicked. I have been having trouble with this as I am relatively new to working with Java Guis. Below is the action listener for the letter buttons.

private class LetterHandler implements ActionListener{

    private char letterVal;

    public LetterHandler(char lv){      
        letterVal = lv;
    }

    //checks if clicked button has the correct value as word char
    public void actionPerformed(ActionEvent e){
        for(int x = 1; x <= selectedWord.wordLength; x++){
            if(selectedWord.wordValue.charAt(x - 1) == letterVal){
//                  JLabel letterValLabel = new  JLabel(String.valueOf(letterVal));
                wordSpacesArray.get(x-1).setName(String.valueOf(letterVal));
                wordSpacesArray.get(x-1).revalidate();
                continue;
            }
            else{
                continue;
            }
        }
        checkWin();
        triesLeft--;
        triesLeftLabel.revalidate();
    }

    //finds if all jlabels are complete or not
    public void checkWin(){
        for(int x = 1; x <= wordSpacesArray.size(); x++){
            String charVal;
            charVal = String.valueOf(wordSpacesArray.get(x-1));
            if(charVal != "?"){
                System.out.println("youWon");
                System.exit(0);
            }
            else{
                break;
            }
            charVal = null;
        }
    }   
}

Any help is appreciated. Let me know if you need for of the programs code Thanks :)

user2280906
  • 53
  • 3
  • 9
  • 1
    Please ask a specific question, not "I have been having trouble doing [x]"; create a program that does nothing but the behavior you cannot understand or make work, and post all of it. Anyone trying to help you with only the information you've provided is just shooting in the dark. – arcy Feb 22 '14 at 21:39
  • Also, if your loop used the traditional 0-based start, everything would be much easier to read: `for(int x = 0; x < selectedWord.wordLength; x++)`. No need for `x - 1` everywhere inside the loop. – JB Nizet Feb 22 '14 at 21:43

1 Answers1

1

There are some issues with the code. However, I'll first try to focus on your current problem:

I assume that wordSpacesArray is a list that contains the JLabels of individual letters of the word.

When this ActionListener will be notified, you try to update the labels in wordSpacesArray with the letter that corresponds to this button. However, in order to update the text that is shown on a JLabel, you have to call JLabel#setText(String) and not JLabel#setName(String). So the line should be

wordSpacesArray.get(x-1).setText(String.valueOf(letterVal));
                      //      ^  Use setText here!

Now, concerning the other issues:

  • As pointed out in the comments, you should use 0-based indexing
  • The calls to revalidate are not necessary
  • The use of continue in its current for is not necessary
  • You should not compare strings with ==, but with equals

    // if(charVal != "?") { ... } // Don't do this!
    if(!charVal.equals("?")){ ... } // Use this instead
    
  • But the charVal in this case will be wrong anyhow: It will be the string representation of the label, and not its contents. So you should instead obtain the text from the label like this:

    // String charVal = String.valueOf(wordSpacesArray.get(x-1)); // NO!
    String charVal = wordSpacesArray.get(x-1).getText(); // Yes!
    
  • The triesLeftLabel will not be updated as long as you don't call setText on it

  • I think the logic of the checkWin method is flawed. You print "You won" when you find the first letter that is not a question mark. I think it should print "You won" when no letter is a question mark.
  • You should not call System.exit(0). That's a bad practice. Let your application end normally. (In this case, maybe by just disposing the main frame, although that would also be questionable for a game...)

So in summary, the class could probably look like this:

private class LetterHandler implements ActionListener
{
    private char letterVal;

    public LetterHandler(char lv)
    {
        letterVal = lv;
    }

    // checks if clicked button has the correct value as word char
    @Override
    public void actionPerformed(ActionEvent e)
    {
        for (int x = 0; x < selectedWord.wordLength; x++)
        {
            if (selectedWord.wordValue.charAt(x) == letterVal)
            {
                wordSpacesArray.get(x).setText(String.valueOf(letterVal));
            }
        }
        checkWin();
        triesLeft--;
        triesLeftLabel.setText(String.valueOf(triesLeft));
    }

    // finds if all jlabels are complete or not
    public void checkWin()
    {
        for (int x = 0; x < wordSpacesArray.size(); x++)
        {
            String charVal = wordSpacesArray.get(x).getText();
            if (charVal.equals("?"))
            {
                // There is still an incomplete label
                return; 
            }
        }

        // When it reaches this line, no incomplete label was found
        System.out.println("You won");
    }
}
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • Wow. I didn't realize how much I had done wrong. Thanks a ton for the help. You really gave solid information on how to improve my program and my coding techniques. I really appreciate it. Thanks :) – user2280906 Feb 23 '14 at 02:57