This discussion is archived
11 Replies Latest reply: Jul 18, 2008 1:16 AM by 843785 RSS

Help with replacing char

843785 Newbie
Currently Being Moderated
I have been working with this code for almost a week now and I cannot figure out what I am doing wrong. The program initializes fine, but when I go to use the ActionListener it goes haywire. The purpose of this code is to mask a string and then unmask the characters one letter at a time, sort of like hangman. I got the mask working, unmasking is where I am seriously stuck. Please can I get some help here in figuring out what I am doing wrong. Code is posted below.
   import javax.swing.*;
   import java.awt.*;
   import java.awt.event.*;
   import java.util.*;
    public class JSecretPhrase extends JApplet implements ActionListener
   {
      JLabel title = new JLabel("Secret Phrase Game");
      JLabel intro = new JLabel("Play our game - guess the phrase");
      JLabel enter = new JLabel("Enter one letter");
      //array of Strings for the random phrase
      String[] secretPhrase = {"PAPAS GOT A NEW PAIR OF SHOES",
                         "LIFE IS A BEACH",
                         "DID YOU GET THE MEMO",
                         "LIVE LAUGH AND LOVE",
                         "A PENNY SAVED IS A PENNY EARNED",
                         "ARE YOU GONNA EAT THOSE TOTS",
                         "LIVE FAST AND RIDE HARD",
                         "LIFE IS LIKE A BOX OF CHOCOLATES",
                         "WOULD YOU LIKE FRIES WITH THAT",
                         "HOOAH ITS AN ARMY THING"};
      JLabel phraseMask = new JLabel("");
      JLabel yesOrNo = new JLabel("");
      JButton[] letter = new JButton[26];
      Font font1 = new Font("TimesRoman", Font.BOLD, 34);
      Font font2 = new Font("TimesRoman", Font.BOLD, 20);
      String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      int rand;
      String phrase, phraseTrue, phraseFix;
      char phraseLtr, buttonLtr, phraseLtrTrue, replaceLtr;
      Container con = getContentPane();
      //random number generator for the selection of the phrase
       public void choosePhrase()
      {
         Random generator = new Random();
         for (int i = 1; i < 11; i++)
         {
            rand = generator.nextInt(10);
         }
      }
       public void init()
      {
         con.setLayout(new FlowLayout());
         con.add(title);
         con.add(intro);
         con.add(enter);
         choosePhrase();
         phraseTrue = secretPhrase[rand];
         phrase = phraseTrue;
         con.add(phraseMask);
         con.add(yesOrNo);
         title.setFont(font1);
         intro.setFont(font2);
         for (int i = 0; i < letters.length(); i++)
         {
            String ltr = Character.toString(letters.charAt(i));
            letter[i] = new JButton(ltr);
            letter.addActionListener(this);
con.add(letter[i]);
}
for (int p = 0; p < phrase.length(); ++p)
{
phraseLtr = phrase.charAt(p);
for (int c = 0; c < letters.length(); ++c)
{
buttonLtr = letters.charAt(c);
if(buttonLtr == phraseLtr)
phrase = phrase.replace(phraseLtr, '*');
}
}
phraseMask.setFont(font2);
phraseMask.setText(phrase);
}
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
for(int s = 0; s < letter.length; ++s)
{
if(source == letter[s])
buttonLtr = letters.charAt(s);
letter[letters.indexOf(buttonLtr)].setEnabled(false);
for(int t = 0; t < phraseTrue.length(); t++)
{
phraseLtrTrue = phraseTrue.charAt(t);
if(phraseLtrTrue == buttonLtr)
{
phraseFix = phrase.replace(phrase.charAt(phraseTrue.indexOf(phraseLtrTrue)), buttonLtr);
phraseMask.setText(phraseFix);
yesOrNo.setText("Correct!");
}
else
{
yesOrNo.setText("Sorry - not in the phrase: " + buttonLtr);
}

}
}
}
}
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
  • 1. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    You've got some major problems there, but the biggest one is that your program is in the form of an applet. That makes it much more difficult than it needs to be for us to test your code. Rewrite it as a JFrame app and you'll have better luck getting help.

    As for your logic errors, the biggest problem I see is the way you're using the replace() method. replace() is already global in its effect; the way you use it in those two {color:000080}for{color} loops, you're doing a whole lot of extra work just to get the wrong result. You can replace the first loop, where you create the masked phrase, with a simple replaceAll():
    String maskedPhrase = phrase.replaceAll("\\S", "*");
    As for unmasking the correctly-guessed characters, look into StringBuilder and its setCharAt() method.

    One other thing: why are you assigning ten random integers to the same variable? ;-)
  • 2. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    First, I want to say thank you for replying. I was beginning to think that this thread was heading into the Forum Abyss. Now, as you were saying...

    uncle_alice wrote:
    You've got some major problems there, but the biggest one is that your program is in the form of an applet. That makes it much more difficult than it needs to be for us to test your code. Rewrite it as a JFrame app and you'll have better luck getting help.
    The problem with rewriting it is that I was thought nothing about JFrame and the class I'm taking is self-paced online, which means all I have to work with is a text book, the API, and any help I can get here. And honestly, with this only being part of my final project and working full time, and a due date of this Saturday I just don't have the time to learn a new Class.
    As for your logic errors, the biggest problem I see is the way you're using the replace() method. replace() is already global in its effect; the way you use it in those two {color:000080}for{color} loops, you're doing a whole lot of extra work just to get the wrong result. You can replace the first loop, where you create the masked phrase, with a simple replaceAll():
    String maskedPhrase = phrase.replaceAll("\\S", "*");
    As for the replaceAll() method, what is "\\S"? I have not worked with regex so I know nothing about it.
    As for unmasking the correctly-guessed characters, look into StringBuilder and its setCharAt() method.
    This I will definitely do. Already looking into it.
    One other thing: why are you assigning ten random integers to the same variable? ;-)
    Because I'm Java stupid :P and I assumed that because I have 10 phrases I needed 10 random integers. How should I write that method? You are the second person to say something about it.
  • 3. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    Container con = getContentPane();
    public class JSecretPhrase extends JFrame implements ActionListener{
      private JPanel pContainer = new JPanel();   
    replace all con with pContainer
    and in your init() add the following lines:
    this.add(pContainer);
    this.setVisible(true);
    call init() from within your constructor
  • 4. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    TrailorParkKid wrote:
    As for the replaceAll() method, what is "\\S"? I have not worked with regex so I know nothing about it.
    It matches any one character that isn't a whitespace character. The line of code I provided just replaces each letter in the phrase with an asterisk while leaving the spaces intact. Here are some regex resources for when you have the time:

    [The Pattern API doc|http://java.sun.com/javase/6/docs/api/java/util/regex/Pattern.html]
    [Sun's Java regex tutorial|http://java.sun.com/docs/books/tutorial/essential/regex/index.html]
    [The best online tutorial and reference site|http://www.regular-expressions.info/] (There are better sites for specific languages like Perl, but this language-neutral site is the best one for Java programmers.)
    One other thing: why are you assigning ten random integers to the same variable? ;-)
    Because I'm Java stupid :P and I assumed that because I have 10 phrases I needed 10 random integers. How should I write that method? You are the second person to say something about it.
    Just get rid of the loop. There may be ten possible values, but you only need one at a time.
  • 5. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    With the exception of removing the loop from the random number generator the code in the OP is unchanged.

    However, I'm trying to use the setCharAt() method and getting a compiler error.

    Code:
    phraseFix = phrase.setCharAt(phraseTrue.indexOf(phraseLtrTrue), buttonLtr);
    Error:
    JSecretPhrase.java:86: cannot find symbol
    symbol  : method setCharAt(int,char)
    location: class JSecretPhrase
                   phraseFix = phrase.setCharAt(phraseTrue.indexOf(phraseLtrTrue), buttonLtr);
                                     ^
    To me its saying that method doesn't exist, but the StringBuilder Class is part of the java.lang package and should be imported automatically. Correct?
  • 6. Re: Help with replacing char
    DarrylBurke Guru Moderator
    Currently Being Moderated
    the StringBuilder Class is part of the java.lang package and should be imported automatically. Correct?
    Correct but irrelevant as your variable phrase is of type String, not StringBuilder. Construct a StringBuilder from phrase and call the method on that.

    db
  • 7. Re: Help with replacing char
    800308 Newbie
    Currently Being Moderated
    TrailorParkKid,

    (I love your handle)

    Yeah, java.lang.* is imported automatically.

    The question is what is phrase. Is it a StringBuilder? ... I suspect it's a String.

    Cheers. Keith.
  • 8. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    corlettk wrote:
    TrailorParkKid,

    (I love your handle)
    lol, 30 years old and I still call myself that. Some things you just never grow out of.

    >
    Yeah, java.lang.* is imported automatically.

    The question is what is phrase. Is it a StringBuilder? ... I suspect it's a String.

    Cheers. Keith.
    I started playing with the StringBuilder Class and had a small breakthrough, but I still have a small issue. Instead of unmasking the entire phrase on the first pressed letter that is in the phrase and making them all the same letter, it only unmasks the entire phrase when the last letter in the phrase is the correctly pressed button and shows the phrase as it should read.

    I suspect that one of my loops is not working as intended, I just don't know how to determine which one and what to change.

    New Code:
    import javax.swing.*;
       import java.awt.*;
       import java.awt.event.*;
       import java.util.*;
        public class JSecretPhrase extends JApplet implements ActionListener
       {
          JLabel title = new JLabel("Secret Phrase Game");
          JLabel intro = new JLabel("Play our game - guess the phrase");
          JLabel enter = new JLabel("Enter one letter");
          //array of Strings for the random phrase
          String[] secretPhrase = {"PAPAS GOT A NEW PAIR OF SHOES",
                             "LIFE IS A BEACH",
                             "DID YOU GET THE MEMO",
                             "LIVE LAUGH AND LOVE",
                             "A PENNY SAVED IS A PENNY EARNED",
                             "ARE YOU GONNA EAT THOSE TOTS",
                             "LIVE FAST AND RIDE HARD",
                             "LIFE IS LIKE A BOX OF CHOCOLATES",
                             "WOULD YOU LIKE FRIES WITH THAT",
                             "HOOAH ITS AN ARMY THING"};
          JLabel phraseMask = new JLabel("");
          JLabel yesOrNo = new JLabel("");
          JButton[] letter = new JButton[26];
          Font font1 = new Font("TimesRoman", Font.BOLD, 34);
          Font font2 = new Font("TimesRoman", Font.BOLD, 20);
          String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
          int rand;
          String phrase, phraseTrue, pLtrT, phraseFix;
          char phraseLtr, buttonLtr, phraseLtrTrue, replaceLtr;
          StringBuilder phraseBuilder = new StringBuilder();
          Container con = getContentPane();
          //random number generator for the selection of the phrase
           public void choosePhrase()
          {
             Random generator = new Random();
             rand = generator.nextInt(10);
          }
           public void changeLetter()
          {
             for(int t = 0; t < phraseTrue.length(); t++)
             {
                phraseLtrTrue = phraseTrue.charAt(t);
                pLtrT = Character.toString(phraseLtrTrue);
             }
          
          }
        @Override
           public void init()
          {
             con.setLayout(new FlowLayout());
             con.add(title);
             con.add(intro);
             con.add(enter);
             choosePhrase();
             phraseTrue = secretPhrase[rand];
             phrase = phraseTrue;
             con.add(phraseMask);
             con.add(yesOrNo);
             title.setFont(font1);
             intro.setFont(font2);
             for (int i = 0; i < letters.length(); i++)
             {
                String ltr = Character.toString(letters.charAt(i));
                letter[i] = new JButton(ltr);
                letter.addActionListener(this);
    con.add(letter[i]);
    }
    phraseBuilder = new StringBuilder(phrase);
    for (int p = 0; p < phrase.length(); ++p)
    {
    phraseLtr = phrase.charAt(p);
    for (int c = 0; c < letters.length(); ++c)
    {
    buttonLtr = letters.charAt(c);
    if(buttonLtr == phraseLtr)
    phrase = phrase.replace(phraseLtr, '*');
    }
    }
    phraseMask.setFont(font2);
    phraseMask.setText(phrase);
    }
    public void actionPerformed(ActionEvent e)
    {
    Object source = e.getSource();
    int phraseIndex = 0;
    String bLtr = null;
    for(int s = 0; s < letter.length; ++s)
    {
    if(source == letter[s])
    buttonLtr = letters.charAt(s);
    bLtr = Character.toString(buttonLtr);
    letter[letters.indexOf(buttonLtr)].setEnabled(false);
    changeLetter();
    phraseIndex = phraseTrue.indexOf(phraseLtrTrue);
    }
    if(pLtrT.equals(bLtr))
    {
    phraseBuilder.setCharAt(phraseIndex,buttonLtr);
    phraseFix = phraseBuilder.toString();
    phraseMask.setText(phraseFix);
    yesOrNo.setText("Correct!");
    }
    else
    {
    yesOrNo.setText("Sorry - not in the phrase: " + buttonLtr);
    }
    }
    }
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
  • 9. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    TrailorParkKid wrote:
    I suspect that one of my loops is not working as intended, I just don't know how to determine which one and what to change.
    Both, and everything. :)

    First, get rid of the "pLtrT" variable; we'll replace it with a local {color:000080}char{color} variable in the actionPerformed() method. That's a terrible name for a variable, by the way. Local variables with short lifespans can have short, cryptic names--in fact, there are many de-facto standard names like 'i' for a loop index or 'ch' for a short-lived {color:000080}char{color}. But most variables, methods, classes, etc. should have names composed of real words, that tell something about their purpose and/or use.

    Get rid of the changeLetter() method, too; like your original choosePhrase() method, all it does is assign several values to the same variable, overwriting the previous value each time. That method is actually the source of the erroneous behavior you described, but it isn't needed anyway, as you'll see.

    Now for the loops. The one in the init() method that masks the phrase is still doing way too much work. Here's a non-regex equivalent of the code I suggested before:
    phraseBuilder = new StringBuilder(phrase);
    for (int p = 0; p < phrase.length(); ++p)
    {
        if (phrase.charAt(p) != ' ')
        {
            phraseBuilder.setCharAt(p, '*');
        }
    }
    In actionPerformed() you've got some code in a loop that doesn't need to be there, while the statement that does the actual unmasking (with the setCharAt() call) should be in the loop but isn't. So get rid of that {color:000080}for{color} loop and everything in it. To figure out which button was pressed and what letter it represents, all you need is this:
    char guessedLetter = e.getActionCommand().charAt(0);
    See, by default, the actionCommand property of the ActionEvent is the same as the text on the button that generated the event. (Bummer, huh?) Now that you know which letter was guessed, use a {color:000080}while{color} loop to find all the places where it occurs in the phrase:
    int phraseIndex = -1, fromIndex = -1;
    boolean wasCorrect = false;
    
    // Use the two-argument form of indexOf() when iterating.
    //
    // The value of an assignment expression is the value that was assigned.
    // This is just a compact way to assign a value and then test it;
    //   you'll find it's a very common practice.
    //
    while ((phraseIndex = phrase.indexOf(guessedLetter, fromIndex)) != -1)
    {
        phraseBuilder.setCharAt(phraseIndex, guessedLetter);
        fromIndex = phraseIndex + 1;
        wasCorrect = true;
    }
    
    if (wasCorrect)
    {
        phraseFix = phraseBuilder.toString();
        phraseMask.setText(phraseFix);
        yesOrNo.setText("Correct!");
    }
    else
    {
        yesOrNo.setText("Sorry - not in the phrase: " + guessedLetter);
    }
    Note the complete absence of the replace() method. That method is supposed to relieve you of the tedium of looping through the original string and creating the new one, etc.; it's normally very useful, but not in this case. Since it has to be told exactly which character to replace, it's no good for the masking operation, where you want to replace "all letters" or "anything but whitespace". Of course replaceAll() can do that easily, but you're not there yet.

    In the unmasking operation, you always replace one character (an asterisk) with one other character (the guessed letter), which sounds like a perfect fit for replace(). Unfortunately, the decision whether to replace any given asterisk depends on its position and the position(s) of the guessed letter in another string. Even replaceAll() couldn't help you with that one.

    So that's why your attempts to use replace() just made things worse. Hey, weren't you supposed to turn this in today?

    :D
  • 10. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    So that's why your attempts to use replace() just made things worse. Hey, weren't you supposed to turn this in today?

    :D
    I actually turned it already, but incomplete. I am trying to work in the corrections right now to get at least some credit. I thank you for taking the time to explain to me what I was doing wrong. Looking at the code you posted and the code I had written I can see where to loops were causing my headaches. Like I posted earlier, I had suspected the loops was what were throwing me off. Again, thank you for the help.
  • 11. Re: Help with replacing char
    843785 Newbie
    Currently Being Moderated
    I managed to integrate the code, but there was still a small bug. Took me a little bit to find it but here it is.

    The masking was not taking place until after I pressed the first button.
    The problem was this line here:
    phraseMask.setText(phrase);
    I made a new tring variable called masked and changed it to this:
     masked = phraseBuilder.toString();
     phraseMask.setText(masked);
    I kept getting a NPE every time I tried to manipulate the code you posted to fix the problem, then I realized the phrase variable was still using the init() version and not the phraseBuilder version. After I fixed that small piece of code the applet worked like a charm. To all of you that helped me with this I would like to thank you all. Hopefully I will be taking the advanced course for Java soon and maybe looking for a class on PHP somewhere as well. Again, thank you all.