3

I am writing a simple program that takes multiple inputs and displays the largest then second largest. My only problem is that I want the program to accept only single digits. I know this goes back to basics, but bear with me. The code I have written so far is:

import javax.swing.JOptionPane;

public class Largest 
{
    public static void main (String args[]) 
    {
        /*Set variables and include a while function to force the program to take
        * ten numbers before proceeding to the rest of the program. */
        int counter = 0;
        int number = 0;
        int largest = 0;
        int second = 0;

        while (counter < 10)
        {
            // Set the counter
            counter++;
            //Input integer, set the largest number as the first output
            number = Integer.parseInt(JOptionPane.showInputDialog("Enter integer"));
            if (number >= largest) {
                largest=number;
            } else if (number >= second && number <= largest) {
                // Set the second largest integer as the output
                second=number;
            }
        }

        //Display the largest number, followed by the second largest number
        System.out.println("Largest number input: " + largest);
        System.out.println("Second largest input: " + second); 

        System.exit(0);             //terminate the application
    }                   //end method main
}                       //end class 
ssantos
  • 16,001
  • 7
  • 50
  • 70
user1798926
  • 39
  • 1
  • 2
  • 4
  • 1
    Do you mean you only want them to able to physically enter one digit (like it won't let you enter 2 characters), or it should only accept one digit (like it would throw an error if it got anything above 9) ? – Parker Nov 05 '12 at 00:28
  • Just realized, the program will always display the second highest number as 0 if it is entered. Not sure why.... – user1798926 Nov 05 '12 at 00:29
  • It should not allow a double digit in any entry. Going back to VB I remember setting the variable to only allow a single digit I believe but that was so long ago – user1798926 Nov 05 '12 at 00:37
  • @user1798926 see my answer. you should just ask again if it is invalid – tckmn Nov 05 '12 at 00:39

3 Answers3

3

For this type of problem, personally, I would use a DocumentFilter

It allows you to restrict the type of characters coming into the field as well as the number of characters.

enter image description here

public class RestrictInput {

    public static void main(String[] args) {
        new RestrictInput();
    }

    public RestrictInput() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JTextField field = new JTextField(2);
                field.setHorizontalAlignment(JTextField.RIGHT);
                ((AbstractDocument) field.getDocument()).setDocumentFilter(new RestrictFilter());
                JPanel panel = new JPanel(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridx = 0;
                gbc.gridy = 0;
                panel.add(new JLabel("Please enter a integer:"), gbc);
                gbc.gridx++;
                gbc.anchor = GridBagConstraints.WEST;
                gbc.weightx = 1;
                panel.add(field, gbc);

                int result = JOptionPane.showConfirmDialog(null, panel, "Input", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
                if (result == JOptionPane.OK_OPTION) {
                    System.out.println("Use entered " + field.getText());
                }

            }
        });
    }

    public class RestrictFilter extends DocumentFilter {

        public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
            String currentText = fb.getDocument().getText(0, fb.getDocument().getLength());
            if (currentText.startsWith("-") || text.equals("-") || fb.getDocument().getLength() < 1) {
                String value = text.substring(0, 1);
                if (value.equals("-")) {
                    if (currentText.startsWith("-")) {
                        super.remove(fb, 0, 1);
                    } else {
                        super.insertString(fb, 0, value, attr);
                    }
                } else if (fb.getDocument().getLength() < 2 && (value.equals("-") || Character.isDigit(value.charAt(0)))) {
                    super.insertString(fb, offset, value, attr);
                }
            }
        }

        public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
            if (length > 0) {
                fb.remove(offset, length);
            }
            insertString(fb, offset, string, attr);
        }
    }
}

Check out MDP's Weblog and Text Component Features, in particular the section of Implementing a Document Filter

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2
//Set the counter
counter++;
while (true) {
    //Input integer, set the largest number as the first output
    number = Integer.parseInt(JOptionPane.showInputDialog("Enter integer"));
    if (number < 10 && number > -10) break; //If it's one digit, it's OK
    JOptionPane.showMessageDialog(null, "Enter only one digit",
        "Too many digits", JOptionPane.ERROR_MESSAGE);
}

What this does is start an infinite loop. If the number is only one digit, it will end the loop and continue on. Otherwise, it will start from the beginning of the loop again and ask for a valid number.

tckmn
  • 57,719
  • 27
  • 114
  • 156
  • 1
    You should check for `number >= 0` as well, or the user could enter negative values with several digits. – FThompson Nov 05 '12 at 00:31
  • Thank you, that is very close to what i just tried. I'm still having a problem with Zero always popping up though, I think I'm going to have to restrict users from entering a zero – user1798926 Nov 05 '12 at 00:50
1

Just use a custom JOptionDialog where you restricted the JTextField to 1 char width.

thedayofcondor
  • 3,860
  • 1
  • 19
  • 28
  • http://stackoverflow.com/questions/3519151/how-to-limit-the-number-of-characters-in-jtextfield – thedayofcondor Nov 05 '12 at 00:42
  • Thank you for the link, I have yet to use limiters – user1798926 Nov 05 '12 at 00:56
  • @MadProgrammer That is what I meant - I was sure JTextField had a "display width" and a "max input length", but then I realised I am confusing it with HTML forms! your answer is definitely more complete, and enforces numeric characters. – thedayofcondor Nov 05 '12 at 00:59