• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

Centralising user input

 
Ranch Hand
Posts: 208
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys

making a class to handle my user input so i dont have to keep writing the same stuff over again.

this is what i came up with:



now i have a few questions:

1) How should I handle printing out my captured input? Should i have each method saving values to a class variable? or should each method type (int, string etc) have another method that prints it out?
   or should i have one method that handles printing of each method (though with different types i dont know how i would do this)
2) Should the methods be static the way I have it, not sure if im on the right track here.

 
Bartender
Posts: 5906
57
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're on the right track here by making a utility class. A couple of comments though:

  • Keep your input utility class separate from any printing class. You'll find over time that your input class will get lengthy and it's best to keep it separated.
  • Scanner can handle inputs from different types of sources. What you've started here is input specific to keyboard entry. I'd suggest renaming your class from the generic "Utility" to "Keyboard". That will help make things clearer as you start to use it in your applications.
  • Make your 'sc' variable private static final.
  • Change your method names to start with "input" instead of "get", e.g. inputYesOrNo(). This avoids confusion with the normal class getters.
  • Your "input" methods should take a String 'prompt' as an argument. Only your application knows a proper description for the information that it's seeking.
  • Instead of using next() or nextInt() or ..., always use nextLine(). A Scanner is designed to allow the inputting of multiple pieces of data at once. Keyboard entry is different, each piece of data should be typed in followed by the "Enter" key. This will, in some places, necessitate the calling of various parsing methods, e.g. Integer.parseInt(). Doing it in this way you can trap for a variety of invalid inputs.
  • Input methods should not be 'void' but should return the appropriate data type, e.g. 'int'.
  • Try not to use "Invalid input" as your error message, it gives the user no hint as to what was incorrect or what was expected.
  • Yes, the methods should be static.

  •  
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Carey
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Carey busy looking at my KeyboardUtility class and everything you said made sense up till:

    Your "input" methods should take a String 'prompt' as an argument. Only your application knows a proper description for the information that it's seeking.
    Sorry I'm not really sure what to do here, i know what you mean, say in this line public static void inputYesOrNo(should a variable go here?) but im still unsure how it will tie together.

    Instead of using next() or nextInt() or ..., always use nextLine(). A Scanner is designed to allow the inputting of multiple pieces of data at once. Keyboard entry is different, each piece of data should be typed in followed by the "Enter" key. This will, in some places, necessitate the calling of various parsing methods, e.g. Integer.parseInt(). Doing it in this way you can trap for a variety of invalid inputs.
    So is my whole check for int if else in the do while loop not neccesary at all? Is everything captured as a string and then converted, im really sorry im very inexperienced with more than the basics.

    Input methods should not be 'void' but should return the appropriate data type, e.g. 'int'.
    ok so a method should always return a value to a variable in order to be used somewhere else in a program, if you dont return a value you are limited by scope?
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You may want to look at my Keyboard class. It's the 15th post down in THIS TREAD.

    wayne brandon wrote:Hi Carey busy looking at my KeyboardUtility class and everything you said made sense up till:

    Your "input" methods should take a String 'prompt' as an argument. Only your application knows a proper description for the information that it's seeking.
    Sorry I'm not really sure what to do here, i know what you mean, say in this line public static void inputYesOrNo(should a variable go here?) but im still unsure how it will tie together.

    Instead of using next() or nextInt() or ..., always use nextLine(). A Scanner is designed to allow the inputting of multiple pieces of data at once. Keyboard entry is different, each piece of data should be typed in followed by the "Enter" key. This will, in some places, necessitate the calling of various parsing methods, e.g. Integer.parseInt(). Doing it in this way you can trap for a variety of invalid inputs.
    So is my whole check for int if else in the do while loop not neccesary at all? Is everything captured as a string and then converted, im really sorry im very inexperienced with more than the basics.

    Input methods should not be 'void' but should return the appropriate data type, e.g. 'int'.
    ok so a method should always return a value to a variable in order to be used somewhere else in a program, if you dont return a value you are limited by scope?





    Notice how prompt methods return a value or stay in an infinite loop until a valid input is given.

    'promptInt()' uses nextLine() instead of nextInt() because the behavior is different for an input of
    ABC 123
     
    Marshal
    Posts: 64680
    225
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Please don't write red text, which some people can't read.

    wayne brandon wrote:. . . Your "input" methods should take a String 'prompt' as an argument. . . . Sorry I'm not really sure what to do here . . .

    Have a look at what I showed you twice in your other threads, with a prompt and limits:-Work out why that misuse of the method should induce it to throw an exception.

    . . . always use nextLine(). . . .

    Not convinced I agree; Use the nextXXX() methods and let the Scanner object do all the work. It is weird that you can enter a line at the keyboard like...and have the three numbers read at different times, but don't worry about that.

    ok so a method should always return a value to a variable . . .

    If your utility classes' methods don't return anything, you can't use them elsewhere. Remember the way I said you should use those methods. Utility classes don't have an existence in their own right; they only exist to provide services to other code.
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:

    . . . always use nextLine(). . . .

    Not convinced I agree; Use the nextXXX() methods and let the Scanner object do all the work. It is weird that you can enter a line at the keyboard like...and have the three numbers read at different times, but don't worry about that.


    By using nextLine() you guarantee that no input processing happens until you press Enter. You also guarantee that no dangling pending characters are left in the input stream.
     
    Campbell Ritchie
    Marshal
    Posts: 64680
    225
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you use nextInt() and similar, you are only processing the part of input you require. That gives the user the option of writing the next part of the input if they so wish.

    I think this is going to be one of those situations where there are two conflicting opinions.
     
    Sheriff
    Posts: 6033
    157
    Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I'm with Carey on this one.  Using all nextLine() methods saves a lot of headaches and gives you the ability to have default values and pauses.
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Campbell

    Do you have a complete keyboard utility class I could look at to study?
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi Carey,

    Im using your class and app and I see how it works!!! I will study it to death...thanks!!!
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Why does making the constructor private stop any instantiation of the class? is it just that the constructor is needed to make an object (default constructor is critical) and if that default constructor cant be reached no object can be created?

    I'm sorry I know you are stopping this Class from being instantiated as it will never need to be an object, but i still dont fully understand why?
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If you provide no constructors then an implicit default constructor will be available to use.

    If you do provide a constructor that is public or protected then that constructor can be used.

    If you provide a constructor that is private then that constructor can only be used inside the class. AND, don't use it inside the class. This essentially prevents any part of your project from trying to create an instance of your utility class.
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Great thanks...

    I see you use a lot of try and catch in your methods to eradicate wrong input types. Is this preferred to something like this? is there a difference?

     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    nextInt() has a couple of drawbacks:

    You can't trap for an empty entry, i.e. someone just presses 'Enter'. This would be handy for example, returning a default value.

    It can leave residue in the input stream that must be dealt with. This is true of all nextXXX() methods EXCEPT for nextLine().

    Behavior can be inconsistent if you use setDelimiter(). Not a problem with nextLine().
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Also, if you look at the source code for nextInt() you will find that it calls Integer.parseInt() and traps for thrown exceptions. Just like I'm doing but then I have control.
     
    Knute Snortum
    Sheriff
    Posts: 6033
    157
    Eclipse IDE Postgres Database VI Editor Chrome Java Ubuntu
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    wayne brandon wrote:Hi Campbell

    Do you have a complete keyboard utility class I could look at to study?


    Here's mine if you're interested:

    https://github.com/ksnortum/Inputer

    Things I like about it:
    * Well documented
    * You can pass validators
    * Default values

    Things I don't:
    * See README TODO
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks so much
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hey Knute if i wanted to add a confirmation

    so like if it asks for a name
    i call a string method

    then it says
    "Are you sure you want this (y/n)"

    can i just add another method checking confirmation at the bottom then have the original method call this?
    whats the best way to do it?
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    There are lots of input scenarios your applications will require over time. Your utility class could end up growing out of control. You'll have to decide if the same structure will be applicable in many cases, and if so, can you write it in a reusable manner.

    Right off the bat, I could see your scenario written one of two ways.

    I would say that in this case the amount of code you'd have to add to the app is small and this would give you more flexibility, so I would suggest against creating yet another new input() method.

    To do this as a reusable input() method you might need these parameters:

     
    Saloon Keeper
    Posts: 2619
    329
    Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Another idea would be rather than creating new methods for each new input feature you may want, would be to have a fixed number of methods probably based on type (String, number, boolean, etc.), and provide the options to use when when prompting.  

    For example:
     
    Ron McLeod
    Saloon Keeper
    Posts: 2619
    329
    Android Eclipse IDE Angular Framework MySQL Database TypeScript Redhat Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Or maybe using fluent/method-chaining type interface:
     
    wayne brandon
    Ranch Hand
    Posts: 208
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thanks Ron!

    can somebody please break this line down for me



    i'm trying my best to understand it.
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    See: Scanner#delimiter() (also .useDelimiter()).

    This is another reason I use nextLine() in my utility, it is unaffected by delimiter.

    Because a keyboard utility will only have a single Scanner object and would probably have a static delimiter() method, it should be called in a static manner, ie Keyboard.delimiter().
     
    Campbell Ritchie
    Marshal
    Posts: 64680
    225
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    My utility class sticks to the default delimiter and doesn't provide any way to change it.
     
    Carey Brown
    Bartender
    Posts: 5906
    57
    Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:My utility class sticks to the default delimiter and doesn't provide any way to change it.


    Do you provide  a wrapper method: nextInt() ?
     
    Don't get me started about those stupid light bulbs.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!