So I've been working on an assignment that requires us to build a "Patient manager", that bases which patient to be treated first based on the emergency level. The main issue I'm running into is that when the user enters something apart from a number into the emergency column, it crashes the program and gives me an InputMismatchException, despite with me attempting to catch it. Any ideas are greatly appreciated!
import java.util.*;
public class PatientManager {
private PriorityQueue<Patient> waitingList;
public PatientManager() {
waitingList = new PriorityQueue<Patient>();
}
// Starter method
public void start() {
String choice;
Scanner in = new Scanner(System.in);
String name;
int emergency = 0;
int order = 0;
Patient patient;
System.out.println("-------------------------------");
System.out.println("(1) New Patient.");
System.out.println("(2) Next Patient.");
System.out.println("(3) Waiting List.");
System.out.println("(4) Exit.");
System.out.println("-------------------------------");
while (true) {
System.out.print("* Choose an item from the menu:");
choice = in.next();
switch (choice) {
case "1":
System.out.println("Enter patient's name:");
name = in.next();
System.out.println("Enter emergency [1 (low) to 5 (life-and-death)]:");
while (true) {
try {
emergency = in.nextInt();
if (emergency >= 1 && emergency <= 5)
break;
else {
System.out.println("(x) Wrong value. Try again:");
emergency = in.nextInt();
}
} catch (Exception e) {
System.out.println("(x) Wrong value. Try again:");
emergency = Integer.parseInt(in.nextLine());
}
}
order++;
patient = new Patient(order, name, emergency);
waitingList.add(patient);
System.out.println("Patient added to the waiting list.");
break;
case "2":
if (waitingList.isEmpty()) {
System.out.println("No more patients.");
} else {
patient = waitingList.remove();
System.out.println(patient.getName() + " is treated.");
}
break;
case "3":
if (waitingList.size() == 0) {
System.out.println("No patients in the list.");
} else {
System.out.println("Waiting list includes:");
Iterator<Patient> iterator = waitingList.iterator();
while (iterator.hasNext()) {
patient = (Patient) iterator.next();
System.out.println("- " + patient.toString());
}
}
break;
case "4":
System.out.println("Program terminated. Good bye!!");
in.close();
System.exit(0);
break;
default:
System.out.println("(x) Wrong choice.");
break;
}
}
}
}
To start with, your code is much more complicated than it needs to be. Replace the whole while loop with this then test again.
while (emergency < 1 || emergency > 5) {
try {
emergency = in.nextInt();
if (emergency < 1 || emergency > 5)
System.out.println("(x) Wrong value. Try again:");
}
catch (Exception e) {
System.out.println("(x) Wrong value. Try again:");
}
}
I managed to fix it. I cleared the result of scanner by just adding in.next() into the catch block. So it looks like this:
catch (Exception e) {
System.out.print("(x) Wrong value. Try again:");
in.next();
System.out.println(emergency);
}
Related
so I'm just finishing up my first computer programming class ever and I'm having problems with my main method. I have 2 classes. The first class is homeClass.java and the other class is homeInventory.java. I'm just going to show you some of my homeInventory.java class unless you smarter ppl feel like it's prudent to have my other class. Basically, I'm having a problem with my else if statements. The program runs w/ the if statement, but won't completely run through the other options (else if). I must be missing something pretty apparent but I'll just see what you have to say on it. Thanks in advance!
public static void main(String[] args) {
ArrayList<homeClass> homes = new ArrayList<>();
Scanner scnr = new Scanner(System.in);
int i = 0;
int j = 0;
String option = "";
String answer = "";
String statusAnswer = "";
do {
System.out.println("Menu:");
System.out.println("1. Add a new home.");
System.out.println("2. Remove a home.");
System.out.println("3. Update home sale status.");
System.out.println("4. Exit");
System.out.print("Option chosen: ");
try {
while(true) {
if(scnr.hasNext()) {
option = scnr.next();
break;
}
}
}
catch (NoSuchElementException NSEE) {
continue;
}
catch (Exception excpt) {
excpt.printStackTrace();
System.out.print("Error, non-integer");
break;
}
try {
if(option.equals("1")) {
homes.add(addHome(scnr));
System.out.println("Home added.");
homes.get(i).getListing();
break;
}
else if (option.equals("2")) {
for(j = 0; j < homes.size(); ++j) {
homes.get(i).getListing();
System.out.print("Remove this listing? Y or N: ");
answer = scnr.next();
if (answer.equalsIgnoreCase("Y")) {
homes.get(i).removeListing();
System.out.println("Home removed.");
}
else if (!answer.equalsIgnoreCase("Y")) {
System.out.println("Home not removed. Choose next option.");
}
}
break;
}
else if (option.equals("3")) {
for(j = 0; j < homes.size(); ++j) {
homes.get(i).getListing();
System.out.print("Do you want to change the sale status? Y or N: ");
answer = scnr.next();
if (answer.equalsIgnoreCase("Y")) {
System.out.println("Enter home sale status: ");
statusAnswer = scnr.next();
homes.get(i).setSaleStatus(statusAnswer);
homes.get(i).getListing();
}
}
break;
}
}
catch (Exception excpt) {
excpt.printStackTrace();
System.out.println("Error, option failed.");
}
} while(!option.equals("4"));
System.out.print("Do you want the home information stored in a file? Y or N: ");
answer = scnr.next();
String outputFileName = "C:\\Temporary\\Home.txt";
for (j = 0; j < homes.size(); ++j) {
String listing = homes.get(i).getListing();
if (answer.equalsIgnoreCase("Y")) {
try {
printToFile(listing, outputFileName);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("File printed to: " + outputFileName);
}
else {
System.out.println("File not printed.");
}
}
scnr.close();
return;
}
}
Stacktrace Here
import java.util.*;
public class AccountClient {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean infiniteLoop = true;
boolean invalidInput;
int id;
// Create array of different accounts
Account[] accountArray = new Account[10];
//Initialize each account array with its own unique id and a starting account balance of $100
for (int i = 0; i < accountArray.length; i++) {
accountArray[i] = new Account(i, 100);
}
do {
try {
//inner loop to detect invalid Input
do {
invalidInput = false;
System.out.print("Enter an id: ");
id = input.nextInt();
if (id < 0 || id > 9) {
System.out.println("Try again. Id not registered in system. Please enter an id between 0 and 9 (inclusive).");
invalidInput = true;
input.nextLine();
}
} while (invalidInput);
boolean exit;
do {
exit = false;
boolean notAnOption;
int choice;
do {
notAnOption = false;
System.out.print("\nMain Menu\n1: check balance\n2: withdraw\n3: deposit\n4: exit\nEnter a choice: ");
choice = input.nextInt();
if (choice < 1 || choice > 4) {
System.out.println("Sorry, " + choice + " is not an option. Please try again and enter a number between 1 and 4 (inclusive).");
notAnOption = true;
}
} while(notAnOption);
switch (choice) {
case 1: System.out.println("The balance for your account is $" + accountArray[id].getBalance());
break;
case 2: {
boolean withdrawFlag;
do {
System.out.print("Enter the amount you would like to withdraw: ");
double withdrawAmount = input.nextInt();
if (withdrawAmount > accountArray[id].getBalance()) {
System.out.println("Sorry, you only have an account balance of $" + accountArray[id].getBalance() + ". Please try again and enter a number at or below this amount.");
withdrawFlag = true;
}
else {
accountArray[id].withdraw(withdrawAmount);
System.out.println("Thank you. Your withdraw has been completed.");
withdrawFlag = false;
}
} while (withdrawFlag);
}
break;
case 3: {
System.out.print("Enter the amount you would like to deposit: ");
double depositAmount = input.nextInt();
accountArray[id].deposit(depositAmount);
System.out.println("Thank you. You have successfully deposited $" + depositAmount + " into your account.");
}
break;
case 4: {
System.out.println("returning to the login screen...\n");
exit = true;
}
break;
}
} while (exit == false);
}
catch (InputMismatchException ex) {
System.out.println("Sorry, invalid input. Please enter a number, no letters or symbols.");
}
finally {
input.close();
}
} while (infiniteLoop);
}
}
The exception code:
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1070)
at java.util.Scanner.next(Scanner.java:1465)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at playground.test.main.Main.main(Main.java:47)
Hello, I made a basic program that uses a class called account to simulate an ATM machine. I wanted to throw an exception if the user didn't type in a letter. This worked fine, however I needed to make it loop so the program didn't terminate after it threw the exception. To do this I just put the try catch in the do while loop I had previously. When I did this though, it's throwing an IllegalStateException every time I type in a letter or choose to exit an inner loop I have which takes the user back to the loop of asking them to enter their id. What is an IllegalStateException, what is causing it in my case, and how would I fix this? Thanks.
It's fairly simple, after you catch the exception the finally clause gets executed. Unfortunately you're closing the scanner within this clause and Scanner.close() closes the underlying input stream (System.in in this case).
The standard input stream System.in once closed can't be opened again.
To fix this you have to omit the finally clause and close the scanner when your program needs to terminate and not earlier.
I am doing voting system for an assignment, 5 classes, votingInterface, votingController, staff, admin, candidates and 3 file.txt (admin, staff, candidate). What I need to do is to modify the code, and allow the staff to enter a password to get voted (which I did) but messy too. If staff fail 3 attempts of staff id, it would go back to the screen. You can see pretty much in this method below. I am new to Java and I need help, please.
public void manageVote()
{
boolean moveOn = false;
while (moveOn == false)
{
System.out.print("Please enter your staff ID :");
String input = getInput();
theStaff = vc.getStaff(Integer.parseInt(input));
if (theStaff != null)
{
String pass = null;
System.out.print("Enter your password");
pass=getInput().trim();
if((theStaff.getPass()).equals(pass))
{
getStaffVote();
//moveOn=true;
}
else
{
System.out.println("Incorrect username/password.");
}
try
{
if(theStaff.hasVoted() == 1)
{
System.out.println("\nYou have voted and cannot vote again\nGood bye...!");
moveOn = true;
}
else if (theStaff.hasVoted() == 0)
{
getStaffVote();
moveOn = true;
}
else
{
System.out.println("There seems to be a problem. Contact your administrator");
}
}
catch(NumberFormatException e)
{
System.out.println("Invalid entry - you must enter a number\nPlease try again");
}
catch(NullPointerException e)
{
System.out.println("Error! Staff ID not found.\nPress ENTER to try again or \"q\" to QUIT : " );
if ("q".equalsIgnoreCase(getInput()))
{
System.out.println("Good bye!");
moveOn = true;
}
}
}
System.out.print("going back to voting screen...");
}
}
You could adjust your code to look like this:
// ...
do{
System.out.print("Please enter your staff ID :");
String input = getInput();
theStaff = vc.getStaff(Integer.parseInt(input));
if(theStaff == null)
System.out.print("No staff with that ID.");
}while(theStaff == null);
boolean isStaffAuthenticated = authenicateUser(theStaff, 3);
if(isStaffAuthenticated){
// Do your logic for when a user is valid staff
doStaffStuff();
}else{
System.out.print("going back to voting screen...");
}
// ...
Where the authenicateUser method looks like this(please notice that I presumed the class name of your Staff object):
public boolean authenicateUser(Staff theStaff, int allowedTries){
int numberOfTries = allowedTries;
do{
String pass = null;
System.out.print("Enter your password");
pass=getInput().trim();
boolean isPassCorrect = (theStaff.getPass()).equals(pass);
if(!isPassCorrect)
System.out.println("Incorrect username/password.");
}while(--numberOfTries > 0 && !isPassCorrect);
return isPassCorrect;
}
Thank you guys for your help, really appreciate it. So here is the solution for my question above. I did manage to ask my tutor after the assignment due, and heres what she recommended. Just want to post this up. Cheers
public void manageVote()
{
boolean moveOn = false;
boolean CheckStaffID = false;
int wrongcheck = 1;
//loop for each voter
while (moveOn == false)
{
try{
while(!CheckStaffID)
{
if(wrongcheck>3)
{
start();
break;//to counter how much times wrong staff id is entered, more than 3 times, back to main screen
}
System.out.print("Please enter your staff ID :");
theStaff = vc.getStaff(Integer.parseInt(getInput()));
if(theStaff!=null)
{
CheckStaffID = true;//find correct staff, stop loop
}
else
{
System.out.println("Incorrect staff ID");
wrongcheck++;//display error message
}
}
System.out.print("Please enter your Password: ");
if(theStaff.getPass().equals(getInput()))
{
if(theStaff.hasVoted() == 1)
{
System.out.println("\nYou have voted and cannot vote again\nGood bye...!");
moveOn = true;
}
else if (theStaff.hasVoted() == 0)
{
getStaffVote();
moveOn = true;
}
else
{
System.out.println("There seems to be a problem. Contact your administrator");
}
}
else
{
System.out.println("Incorrect Password.");//password error message display
CheckStaffID = false;//to re-enter staff logging system
}
}
catch(NumberFormatException e)
{
System.out.println("Invalid entry - you must enter a number\nPlease try again");
}
/*catch(NullPointerException e)
{
System.out.println("Error! Staff ID not found.\nPress ENTER to try again or \"q\" to QUIT : ");
if ("q".equalsIgnoreCase(getInput()))
{
System.out.println("Good bye!");
moveOn = true;
}
}*///already have else to catch error, so comment this code
}
System.out.print("going back to voting screen...");
}
I was having some problem when try to try catch the IndexOutOfBoundsException for a List in Java. So I declared my list with 2 elements as:
List<String> list = new ArrayList<>(Arrays.asList("item1", "item2"));
Then I tried to do a try catch:
do {
for (int i = 0; i < list.size(); i++) {
System.out.print("(" + (i + 1) + ")" + list.get(i));
}
System.out.println(" ");
try{
option = sc.nextInt();
} catch (IndexOutOfBoundsException e){
System.out.println("Invalid option");
sc.next();
continue;
} catch (InputMismatchException e) {
System.out.println("Option input mismatch.");
sc.next();
continue;
}
sc.nextLine();
if (option == 1) {
System.out.print("Enter name: ");
// scanner takes in input
} else if (option == 2) {
System.out.print("Enter desc: ");
// scanner takes in input
}
type = list.get((option - 1));
} while (option <= 0 || option >= 3);
However, when I entered anything larger than 2 for option, it threw me IndexOutOfBounds exception but I thought I did a try catch for it already?
Thanks in advance.
do {
for (int i = 0; i < list.size(); i++) {
System.out.print("(" + (i + 1) + ")" + list.get(i));
}
System.out.println(" ");
try {
option = sc.nextInt();
} catch (IndexOutOfBoundsException e) {
System.out.println("Invalid option");
sc.next();
continue;
} catch (InputMismatchException e) {
System.out.println("Option input mismatch.");
sc.next();
continue;
}
sc.nextLine();
if (option == 1) {
System.out.print("Enter name: ");
// scanner takes in input
} else if (option == 2) {
System.out.print("Enter desc: ");
// scanner takes in input
}
try {
type = list.get((option - 1));
} catch (IndexOutOfBoundsException e) {
System.out.println("Invalid option");
option=3;
}
} while (option <= 0 || option >= 3);
I have added new try-catch at type = list.get((option - 1));
To force user re-input option, I will set option to 3 at the catch cause
You are not going to catch the exception if you don't use an invalid value to call the list.
ArrayList<String> list = new ArrayList<>(Arrays.asList("item1", "item2"));
Scanner sc = new Scanner(System.in);
int option;
try {
option = sc.nextInt();
System.out.println(list.get(option));
} catch (IndexOutOfBoundsException e) {
System.out.println("Invalid option");
} catch (InputMismatchException e) {
System.out.println("Option input mismatch.");
}
sc.close();
You also can do it like this, it will loop till you enter a valid value and after a valid value is entered ask for name or whatever(not implemented)
ArrayList<String> list = new ArrayList<>(Arrays.asList("item1", "item2"));
Scanner sc = new Scanner(System.in);
int option = 0;
while(!(option == 1 || option==2) ) {
try {
option = sc.nextInt();
} catch (InputMismatchException e) {
System.out.println("Option input mismatch.");
}
}
System.out.println(list.get(option-1));
sc.close();
Just a little confused as to what is happening here. The point of this error trap is, for example, the user inputs 3 numbers/letters instead of a 4 digit number. This error trap was designed loop the question until the user gets it right. However it instead loops the error message. Can anyone give some pointers as to what is going on?
JFrame Error = new JFrame ();
String input = JOptionPane.showInputDialog(null,"Enter the 4 digit resistor values:");
while (true){
try{
int numInput = Integer.parseInt (input);
if (numInput >= 1000) {
break;
}
else {
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
catch (Exception e){
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
You need to move code for ask the input to the loop.
JFrame Error = new JFrame ();
String input = null;
while (true){
try{
input = JOptionPane.showInputDialog(null,"Enter the 4 digit resistor values:");
int numInput = Integer.parseInt (input);
if (numInput >= 1000) {
break;
}
else {
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
catch (Exception e){
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
As JacobM mentioned, you need to ask for the input inside the while loop. When the catch clause terminates, the next thing your code does will be the first thing in the while loop.
JFrame Error = new JFrame ();
while (true){
String input = JOptionPane.showInputDialog(null,"Enter the 4 digit resistor values:");
try{
int numInput = Integer.parseInt (input);
if (numInput >= 1000) {
break;
}
else {
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
catch (Exception e){
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
You need to ask for a new value, inside the loop. change it to:
String input;
try {
while (true){
input = JOptionPane.showInputDialog(null,"Enter the 4 digit resistor values:");
int numInput = Integer.parseInt (input);
if (numInput >= 1000) {
break;
}
else {
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(Error,"Invalid Input.");
}