Results 1 to 5 of 5
  1. #1
    floppyspace is offline Member
    Join Date
    Mar 2010
    Posts
    3
    Rep Power
    0

    Default Menu-driven console help please

    Hi

    I know their was a query on menus before but mine is a little more simple, just feel I have missed something simple.

    My issue is that my menu is made up of

    System.out.println(" A. Check if number is in Fibonacci sequence.");
    System.out.println(" B. Basic savings calculator.");
    System.out.println(" X. Exit the program");

    so i use a scanner

    Scanner scan = new Scanner(System.in);
    String box = scan.next();

    I think an if statement should work but error comes up when i try to call it with A,B,X all is well for everything if I set it as integers and label them as 123

    example of what im using
    if (box == A)
    {
    checkfibonacci();
    }
    String B = new String(box);

    else if(box == B)
    {
    savingsacct();
    }
    etc.

    I don't want the answer I just want were and what I should be looking at to get the answer : ) , think may be I am missing an object but...:confused:

    I am studying via correspondence so no one to bounce ideas of and trawling the net has come to no avail (may be looking for wrong thing me thinks).

    many thanks
    floppy

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    If you are comparing Strings, never use == but instead use the equals(...) or equalsIgnoreCase(...) methods.

  3. #3
    floppyspace is offline Member
    Join Date
    Mar 2010
    Posts
    3
    Rep Power
    0

    Default

    thanks, that makes sense :)

    cheers for quick reply :D
    floppy

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,371
    Blog Entries
    7
    Rep Power
    20

    Default

    I wrote a little article for another forum a while ago; maybe it can be a bit of help to you; here it is:

    A Simple Text-Based Menu System

    The Design

    I want to implement a simple text base menu system; menus can be part of another menu (or more of them). Selecting an option (a 'menu item') either opens up another menu or it activates some code. When that code has finished the same menu will be displayed again. A user must be able to navigate 'upwards' again, i.e. the menu that contains the current menu as an item will be displayed again. A user must also be able to quit the entire thing.

    When you think of it: it doesn't make sense to navigate upwards when the current menu is the top menu; we'll make that navigation optional. Also we don't want the user to be able to quit everything in every single menu; we'll make that an optional feature also.

    Because this is a simple text based menu system we'll display the options as simple Strings of text on the console prepended by a number like this:

    Menu title:
    0: first option
    1: second option
    2: third option
    ...

    And we prompt the user to type 0, 1, 2, ... upto n-1 where there are n options in the menu. Of course an incorrect input deserves a warning and a retry. The 'quit' and 'back' options will be the last options (if present) in any menu.

    A TextMenuItem

    What exaclty is a menu item? It is represented by a single line of text and a piece of code that has to be executed when the item is selected. That's easy enough; here is the TextMenuItem class:

    Java Code:
    package textmenu;
    
    public class TextMenuItem implements Runnable {
    	
    	private String title;
    	private Runnable exec;
    
    	protected TextMenuItem(String title) { this(title, null); }
    
    	public TextMenuItem(String title, Runnable exec) {
    		this.title= title;
    		this.exec= exec;
    	}
    	
    	public String getTitle() { return title; }
    	
    	public boolean isExec() { return exec != null; }
    	
    	protected void setExec(Runnable exec) { this.exec= exec; }
    	
    	public void run() {
    		
    		try {
    			exec.run();
    		}
    		catch (Throwable t) {
    			t.printStackTrace(System.err);
    		}
    	}
    }
    The constructor of this class takes a String title and an optional piece of code to be executed when the item is selected. Of course that piece of code may throw an Exception of some sort and we'll catch that and display the Exception stack trace.

    I decided to model that piece of code as a Runnable. See the API documentation for all the details of that interface. You can find a link to that documentation in the first post of the 'Answers' section of the Java forum. It is strongly advised to download the documentation and keep it stored on your local harddisk somewhere, you'll need it more often than not.

    Back to that class: it has a single 'getter' for the title and a 'setter' for the executable piece of code (the Runnable). We can also check whether or not such a piece of code was set previousle by the 'isExec()' method.


    The TextMenuItem class itself also implements the Runnable interface and (thus) it has implemented a 'run()' method. All it does is blindly call the 'run()' method from the executable piece of code and catch any Exceptions (Throwables) it may throw.

    But what if the exec member variable is null? Who or what takes care of that? Think a bit: a TextMenuItem will only be selected from a menu; there are no orphan TextMenuItems. A TextMenu will take care of that. By convention only the 'back' TextMenuItem will have a null exec member variable, all other TextMenuItems must have a non-null exec member variable; that is one of the reasons why the first constructor isn't public because I don't want anyone to call it and ruin the game.

    If you take a close look at that first constructor you'll see that it is a protected constructor. This implies that it can only be called from the class itself and from its sub-classes. The others (the users) have to call the second constructor.

    A menu also shows itself as a single line of text in another menu (unless it is a top-level menu of course). So in a way a TextMenu is a TextMenuItem and can be a sub-class of this first class.

    What's the task of a TextMenu when it is selected? Basically it has to display all of its TextMenuItems, prompt the user to select one of them and execute that TextMenuItem; all the TextMenu has to do is call its 'run()' method; with one single exception: if the TextMenuItem returns false when its 'isExec()' method is called the 'back' option was selected and the currently running TextMenu has to return from its own 'run()' method. Think a bit about this and it'll make sense.

    A TextMenu

    First I'll show the class (it's quite a bit bigger than the first one but it does a lot more) and then we'll disect all the code; here it is:

    Java Code:
    package textmenu;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class TextMenu extends TextMenuItem {
    	
    	private static final TextMenuItem quit= new TextMenuItem("quit", new Runnable() {
    		public void run() {
    			System.exit(0);
    		}
    	});
    	
    	private static final TextMenuItem back= new TextMenuItem("back");
    
    	List<TextMenuItem> items;
    
    	public TextMenu(String title, TextMenuItem ... items) { this(title, false, true, items); }
    
    	public TextMenu(String title, boolean addBack, boolean addQuit, TextMenuItem ... items) {
    		super(title);
    		setExec(this);
    
    		initialize(addBack, addQuit, items);
    	}
    	
    	private void initialize(boolean addBack, boolean addQuit, TextMenuItem ... items) {
    		
    		this.items= new ArrayList<TextMenuItem>(Arrays.asList(items));
    		if (addBack) this.items.add(back);
    		if (addQuit) this.items.add(quit);
    	}
    	
    	private void display() {
    		
    		int option= 0;
    		System.out.println(getTitle()+":");
    		for (TextMenuItem item : items) {
    			System.out.println((option++)+": "+item.getTitle());
    		}
    		System.out.print("select option: ");
    		System.out.flush();
    	}
    	
    	private TextMenuItem prompt() throws IOException {
    		
    		BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
    
    		while (true) {
    
    			display();
    		
    			String line = br.readLine();
    			try {
    				int option= Integer.parseInt(line);
    				if (option >= 0 && option < items.size())
    					return items.get(option);
    			}
    			catch (NumberFormatException e) { }
    		
    			System.out.println("not a valid menu option: "+line);
    		} 
    	}
    	
    	public void run() {
    	
    		try {
    			for (TextMenuItem item= prompt(); item.isExec(); item= prompt())
    				item.run();
    		}
    		catch (Throwable t) {
    			t.printStackTrace(System.out);
    		}
    	}
    }
    The class is stored in the same package as the first one and it extends from it so it is a TextMenuItem. More important is that it can call that first protected constructor from its super-class. It has to be able to do that because of an idiosyncracy of the Java language that forbids us something else. We'll discuss that later.

    The first few lines of this class define two private static members: a 'back' menu item and a 'quit' menu item. We don't want the user to pass those in explicitly so we define them here and let the TextMenu do the work.

    Both constructors take a String title and a list of TextMenuItems to populate the current menu. The second constructor also takes two boolean parameters telling it whether or not to add a 'back' menu item and/or a 'quit' menu item.

    If you look at the second constructor it calls the protected constructor of its super-class, sets itself as the piece of executable code and initializes itself. Why didn't it call the other super-class constructor as in:

    Java Code:
    super(title, this);
    After all it represents the Runnable code associated with the menu. When a constructor calls its super-class constructor there is no 'this' yet. Java forbids those fancy things (and rughtly so for reasons that are beyond this little article).

    So the constructor sets just the title by calling its protected super-class constructor and sets itself as the runnable piece of code in the second step by calling the protected 'setExec()' method in its super-class. Nothing outside of the class hierarchy can do the same and we want it to be that way. That way turned Javas idiosyncracy into a good thing ...

    The private 'initialize()' methods builds the entire menu: it creates a List of a copy of all the TextMenuItems and optionally adds a 'back' and a 'quit' menu item. Why does it create a copy of a list that already is a copy of all the TextMenutems? The first list is a 'write through' list (read the API documentation); this means that if someone outside these classes changes something in the array the changes will shine through in the list. We don't want that so we make a copy of that first list. The fist list is also a fixed-sized list and if we want to add other TextMenuItems to a menu later we won't be able to do that.

    What happens when this menu is selected from another menu? It's 'run()' method will be called; it basically does this:

    Java Code:
    for (TextMenuItem item= prompt(); item.isExec(); item= prompt())
    	item.run();
    Here you need to know how a 'for' statement works: first the 'prompt()' method is called which returns a selected TextMenuItem; if the item is not executable the loop quits. It it is the item has its 'run()' method called and finally the user is prompted again.

    In the original method body you can see that if something goes wrong (an Exception is thrown), the method catches it, displays it and terminates the execution of the current menu. What else should it do except displaying what went wrong? In a more industrial strength menu system more clever exception handling might be implemented but we'd like to keep it simple for now.

    We're getting into the details of the menu handling; the body of the 'prompt()' method looks like this:

    Java Code:
    BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
    
    	while (true) {
    
    		display();
    		
    		String line = br.readLine();
    		try {
    			int option= Integer.parseInt(line);
    			if (option >= 0 && option < items.size())
    				return items.get(option);
    		}
    		catch (NumberFormatException e) { }
    		
    		System.out.println("not a valid menu option: "+line);
    	}
    First it sets up a BufferedReader for the System.in stream because we want to read entire lines from the (console) input. We want the user to type an integral number between 0 and n-1 where n is the size of the 'items' list. If something goes wrong it catches the Exception, prints a warning and repeats the prompting; if all went well the selected TextMenuItem is returned. The method always displays the entire menu before user input is expected.

    Note that we only catch Exceptions thrown because of incorrect input, not because some pet parrot chew the wire of your keyboard or something evn more desastrous. Such events will most likely throw another type of Exception. Such Exceptions are handled by the 'run()' method that called this method and it will print the Exception stack trace and terminate as well.

    The last thing that needs to be done is displaying an entire menu: the title of the TexTMenu is displayed followed by a numbered list of TextMenuItems; this is not especially rocket science and you can figure out for yourself what the following code does:

    Java Code:
    int option= 0;
    System.out.println(getTitle()+":");
    for (TextMenuItem item : items) {
    	System.out.println((option++)+": "+item.getTitle());
    }
    System.out.print("select option: ");
    System.out.flush();
    That's about it; all we have to do is build a little test code that plays with our menu system. Our code uses two menus, a top-level menu like this:

    top menu:
    0: item 1
    1: nested menu
    2: quit

    and a nested menu like this:

    nested menu:
    0: item 2
    1: item 3
    2: back

    Note that the top-level menu has a 'quit' item but no 'back' item while the nested menu has no 'quit' item but it does have a 'back' item. Here is the test code; it's a bit boring but it does what it has to do and it exercises the menu system a bit:

    Java Code:
    public class TestTextMenu {
    	
    	private static TextMenuItem item1= new TextMenuItem("item 1",new Runnable() {
    		public void run() {
    			System.out.println("running item 1");
    		}
    	});
    	
    	private static TextMenuItem item2= new TextMenuItem("item 2",new Runnable() {
    		public void run() {
    			System.out.println("running item 2");
    		}
    	});
    
    	private static TextMenuItem item3= new TextMenuItem("item 3",new Runnable() {
    		public void run() {
    			System.out.println("running item 3");
    		}
    	});
    
    	private static TextMenu nestedMenu= new TextMenu("nested menu", true, false, item2, item3);
    	private static TextMenu topMenu= new TextMenu("top menu", false, true, item1, nestedMenu);
    
    	public static void main(String[] args) {
    		
    		topMenu.run();
    	}
    }
    The code builds the three TextMenuItems and the two TextMenus; the 'main()' methhod runs the top-level menu. That's it for now, do with the code what you want; it can be enhanced in several ways:

    Display the menus and prompts by using JOptionPanes;
    Have more advanced navigation options (try a 'top' item for starters);
    Have help text available;
    Make it behave like JMenus and JMenuItems (read the API documentation);
    Make the 'quit' item a bit more polite;

    kind regards,

    Jos

  5. #5
    floppyspace is offline Member
    Join Date
    Mar 2010
    Posts
    3
    Rep Power
    0

Similar Threads

  1. how to create menu-driven programs?
    By princess.blue in forum Eclipse
    Replies: 0
    Last Post: 12-07-2009, 08:01 AM
  2. message driven beans
    By rob in forum Java Servlet
    Replies: 0
    Last Post: 03-12-2009, 08:01 PM
  3. Menu driven system - atm
    By thelinuxguy in forum Advanced Java
    Replies: 1
    Last Post: 02-18-2009, 11:14 PM
  4. Replies: 1
    Last Post: 07-13-2008, 03:16 PM
  5. Replies: 7
    Last Post: 05-09-2008, 07:54 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •