I'm having some issues with one of my bonus assignments for school. In my code the purpose of the project is posted, but this is what I have so far.

/********************************************
 *File Name: Combination (Assignment 8 Part 1)
 *Purpose: Create a frame with ten buttons, labeled 0 through 9 (Hint: You may create an array of
 *10 buttons). To exit the program, the user must click on the correct three buttons in order, 
 *something like 7-3-5. If the wrong combination is used, a JOptionPane message, "Wrong, try again,"
 *will be displayed. You may use GridLayout Manager to arrange the buttons nicely.
 *Programmer: Shanel Fowler
 *Date: 5/14/14
 ********************************************/

 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;

 public class Combination extends JFrame
 {
    private JPanel panel = new JPanel();
    private String input;
    private String passCode = "247";
    private int count = 0;

    //Created ten JButton to add to the panel.                      
    private JButton zero    = new JButton("0");
    private JButton one     = new JButton("1");
    private JButton two     = new JButton("2");
    private JButton three   = new JButton("3");
    private JButton four    = new JButton("4");
    private JButton five    = new JButton("5");
    private JButton six     = new JButton("6");
    private JButton seven   = new JButton("7");
    private JButton eight   = new JButton("8");
    private JButton nine    = new JButton("9");


    //Created a constructor to set the title, size, and whether or not the window is visible.
    public Combination()
    {
        setTitle("Lock");
        setSize(250, 100);

        createComponents();
        pack();

        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    //Created components method to determine what will be displayed and sent into the panel.
    public void createComponents()
    {
        panel.setLayout(new GridLayout(2,5));


        createNumButtons();

        //Adds the panel to the frame.
        add(panel); 
    }

    public void createNumButtons()
    {
        //Adds the buttons to the panel.
        panel.add(zero);
        panel.add(one);
        panel.add(two);
        panel.add(three);
        panel.add(four);
        panel.add(five);
        panel.add(six);
        panel.add(seven);
        panel.add(eight);
        panel.add(nine);


        buttonListener listen = new buttonListener();


        zero.addActionListener(listen); 
        one.addActionListener(listen);          
        two.addActionListener(listen);      
        three.addActionListener(listen);    
        four.addActionListener(listen); 
        five.addActionListener(listen); 
        six.addActionListener(listen);      
        seven.addActionListener(listen);    
        eight.addActionListener(listen);    
        nine.addActionListener(listen); 
    }

    /**
     *Allow the user to click three buttons. If the combination is incorrect display to the screen
     *that the entry was incorrect and to try again. Keep repeating the process until the user has
     *correctly entered the pass code.
     */
    private class buttonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            StringBuffer temp = new StringBuffer();

            //Determines what will be done based on the user's selection.
            while(count < 3)
            {
                if(zero.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(one.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(two.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(three.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(four.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(five.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(six.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(seven.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(eight.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
                if(nine.isSelected())
                {
                    input = e.getSource().toString();
                    temp.append(input);
                    count++;
                }
            }

            if(temp.equals(passCode))
            {
                JOptionPane.showMessageDialog(null, "That is correct!");
            }
            else
            {
                JOptionPane.showMessageDialog(null, "That not correct. Please try again.");
                while(count < 3)
                {
                    if(zero.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(one.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(two.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(three.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(four.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(five.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(six.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(seven.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(eight.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                    if(nine.isSelected())
                    {
                        input = e.getSource().toString();
                        temp.append(input);
                        count++;
                    }
                }
            }

        }
    }

    public static void main(String[] args)
    {
        Combination obj = new Combination();
    }
 }

What is it that you are having trouble with? Where are your errors in the code if you have any?

  • use JToggleButtons in loop, add ActionListener (already used)

  • you created a new Scanner in every..., how did you want to put that together, remove every code lines in ActionListener, only append String value from e.getSource, there no need to test for every Objects, don't to complicate simple things, create void unlock and if counter raised 3 then to call this void (current JVM should be terminated on success), if success to call

  • create local int variable as counter, and String variable for unlock (there isn't requirement to parse to the integer:-)

  • test for correctness (isSelected) after counter/three JToggleButtons ...., remove all code lines inside, there isn't important to otherwise to 1. reset all JToggleButtons (setSelected(false)) and 2. counter to default value, unlock to "", 4. then to show JOptionPane

  • up to 50 code lines incl. impelmenting a Initial Thread in main class, theoretically you can to use JButtons instead JToggleButtons

Edited 2 Years Ago by mKorbel

@TheFearful
From what I've tested so far there are no known errors that my compiler has picked up, just when a button is selected the program freezes entirely, it has something to do with my statements in the actionPerformed method.

@mKorbel
Thank you for replying with fresh ideas, I'm relatively new at this and haven't looked into JToggleButtons, so I check out the oracle tutorials and API to get a better understanding of it. Since I am not that comfortable with the usage of JToggleButtons, theoretically speaking, what are some ideas or ways of doing this in JButton. Initially, my plan was to append the values into some string and compare it with my pass code.

Everything to do with Swing (eg painting the screen, running actionPerformed methods) happens on a single thread - the "Event Dispatch Thread", or "EDT", or "Swing thread". Your actionPerformed is run on the EDT, which means that once your actionPerformed method starts NOTHING else will happen in Swing - no button clicks will be processed, no screen updates, nothing. You just sit in your loop burning 100% of the CPU time waiting for a count of 3 that will never happen because no button can be selected.
In your actionPerformed you just update a variable to record which buttons were pressed, and if there are now 3 buttons then unlock or error. No loops!

Your idea ofappending into a String is OK. In your actionPerformed you can query the ActionEvent to see which button was clicked, then get the text of that button to append. No need for all those horrible repeated if tests.

Your code would be shorted and simpler if you follow the Hint and use an array of 10 buttons rather than 10 separate variables.

Edited 2 Years Ago by JamesCherrill

@JamesCherrill
Thank you for the response and you were right. I've changed the code because of your statements and have added a line in my actionPerformed method to test each button press.

Updated Code is below:

/********************************************
 *File Name: Combination (Assignment 8 Part 1)
 *Purpose: Create a frame with ten buttons, labeled 0 through 9 (Hint: You may create an array of
 *10 buttons). To exit the program, the user must click on the correct three buttons in order, 
 *something like 7-3-5. If the wrong combination is used, a JOptionPane message, "Wrong, try again,"
 *will be displayed. You may use GridLayout Manager to arrange the buttons nicely.
 *Programmer: Shanel Fowler
 *Date: 5/14/14
 ********************************************/

 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;

 public class Combination extends JFrame
 {
    private JButton[] numbers = {new JButton("0"),new JButton("1"),new JButton("2"),new JButton("3"),new JButton("4"),
                            new JButton("5"),new JButton("6"),new JButton("7"),new JButton("8"),new JButton("9")};
    private JPanel panel = new JPanel();    
    private String passCode = "247";                
    private String input;


    //Created a constructor to set the title, size, and whether or not the window is visible.
    public Combination()
    {
        setTitle("Lock");
        setSize(250, 100);

        createComponents();
        pack();

        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    //Created components method to determine what will be displayed and sent into the panel.
    public void createComponents()
    {
        panel.setLayout(new GridLayout(2,5));


        createNumButtons();

        //Adds the panel to the frame.
        add(panel); 
    }

    public void createNumButtons()
    {
        buttonListener listen = new buttonListener();

        for(int i = 0; i < numbers.length; i++)
        {
            panel.add(numbers[i]);
            numbers[i].addActionListener(listen);
        }           
    }

    /**
     *Allow the user to click three buttons. If the combination is incorrect display to the screen
     *that the entry was incorrect and to try again. Keep repeating the process until the user has
     *correctly entered the pass code.
     */
    private class buttonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            JOptionPane.showMessageDialog(null, e.getActionCommand());
        }
    }

    public static void main(String[] args)
    {
        Combination obj = new Combination();
    }
 }

That looks 100% better - you're really on the right track now.
It's especially good that you stopped there and added a line to allow you to test what you did so far. Real programmers test early and test often.

@JamesCherrill
Thank you very much for your help. I tried to experiment with the idea of storing the presses into a string and comparing, though once again I could just be overcomplicating it. I wrote up something that looks a little like this:

while(!(input.equals(passCode)))
            {
                for(int i = 0; i < 3; i++)
                {
                    input = e.getActionCommand();
                    bld.append(input);
                }

                input = bld.toString();
                if(input.equals(passCode))
                    break;
                else
                    JOptionPane.showMessageDialog(null, "Wrong, try again.");
            }

Edited 2 Years Ago by AbstractEden

  • wrong, not (enless loop = while), you have to add counter inside ActionPerformed,

  • there to a) increase counter, and b) getText from e.getSource,

  • if(counter == 3) to test if(passCode.equals(input)),

Edited 2 Years Ago by mKorbel

Like mKorbel says:
You can't do this with a 1..3 loop. Each time a button is pressed append it to the combination String. When that results in a String of length 3, check to see if it's right or wrong.

Alright, went back and removed a few things then changed it to this:

bld.append(e.getActionCommand());
                counter++;

                if(counter == 3)
                {
                    input = bld.toString();

                    if(input.equals(passCode))
                        JOptionPane.showMessageDialog(null, "Correct.");
                    else
                        JOptionPane.showMessageDialog(null, "Wrong, try again.");
                }

Edited 2 Years Ago by AbstractEden: Changed if to while

No need for the counter - it's just another thing that could go wrong. You can use the length of the bld String and see if that is 3. Don't forget to reset it back to "" after a wrong entry

Edited 2 Years Ago by JamesCherrill

Interesting task you have there :) I'd assume that you've got it running by now but this is what i'd try

public void actionPerformed(ActionEvent e){
                    bld = (e.getActionCommand());
                    sb.append(bld);
                    if (sb.length()== 3) {
                        input = sb.toString();
                        if (input.equals(pass)){
                            JOptionPane.showMessageDialog(frame,"Success");
                            frame.dispose();
                        }
                        else{
                            JOptionPane.showMessageDialog(frame, "Wrong!");
                            sb.setLength(0);
                            failedAttempts++;
                            if (failedAttempts == 3){
                                JOptionPane.showMessageDialog(frame, "Your have ran out of attempts!");
                                frame.dispose();
                            }
                        }
                    }
                  }

@Slavi, you shouldn't give away the whole method definition. Besides, there is a bug which could cause an infinite loop if the e.getActionCommand() returns a value that cuases the result of "append()" to go over the length of 3 (may not occur in this application but easily mislead in other application). Therefore, giving a suggestion of the code this way should always explain what you are doing and what may be the pit fall because the code itself has specific use only.

@Slavi
Thank you for the reply. Currently, I have something that is similar in nature minus my original counter, but as Taywin has posted I might have overlooked something. Still looking over that section to see if I could make it as clear as possible.

I apologize for the long wait. Had finals, but this is where I currently left off:

private class buttonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            bld.append(e.getActionCommand());   

            int size = bld.length();
            if(size == 3)
            {
                input = bld.toString();

                if(input.equals(passCode))
                    JOptionPane.showMessageDialog(null, "Correct.");
                else
                {
                    JOptionPane.showMessageDialog(null, "Wrong, try again.");
                    size = 0;
                }

            }   
        }
    }

You should incorporate Taywin's point and test for size >= 3
The problem may never happen with this application, but that kind of "defensive programming" is a good habit to develop. In real life programs get updated long after they were first written, and often by another programmer. If you use size == 3 you have an infinite loop just waiting to happen...

Edited 2 Years Ago by JamesCherrill

Would it be horrible to place that check within the same if statement. Example:

if(size == 3 || size >= 3)

Or would it be best to have them separated for clarity. So if size >= 3 then set the length to 0.

If size == 3 is true, then we know that size >= 3 is true, so (size == 3 || size >= 3) is equivalent to (size >= 3). So just use the latter.

If you can, you should 'collect' togeather your conditional statements, unless you need to split them for easy of reading.

This question has already been answered. Start a new discussion instead.