Exception handling in JTextField - java

I am writing a restaurant application.
In this part, in order to add cook, user needs to enter cook's name in a nameTextField and cook's salary in a salaryTextField and at the name part I want to prevent the user from entering numbers and at the salary part I want to prevent the user from entering words. For salary part I tried to use exception handling but couldn't really succeed.
class AddButtonInCookClick implements ActionListener{
public void actionPerformed(ActionEvent e) {
String name = (String)nameTextFieldCook.getText();
double salary = new Double(0.0);
try {
salary = Double.parseDouble(salaryTextField.getText());
}catch(NumberFormatException ex) {
System.out.println(ex);
}
restaurant.getEmployees().add(new Cook(id, name, salary));
id++;
JOptionPane cookOptionPane = new JOptionPane();
JOptionPane.showMessageDialog(cookOptionPane, "Cook added succesfully.");
}
}
addButtonInCook.addActionListener(new AddButtonInCookClick());
Even though the program doesn't crush. I still can't make user enter numbers for salary part. Thank you for helping.

You can restrict input solely to numerals by using JFormattedTextField in lieu of a normal JTextField.
Sample code:
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import java.text.NumberFormat;
import javax.swing.text.NumberFormatter;
public class Test extends JFrame
{
JFormattedTextField salaryFormattedTextField;
NumberFormat numberFormat;
NumberFormatter numberFormatter;
public Test()
{
numberFormat = NumberFormat.getInstance();
// delete line if you want to see commas or periods grouping numbers based on your locale
numberFormat.setGroupingUsed(false);
numberFormatter = new NumberFormatter(format);
numberFormatter.setValueClass(Integer.class);
// delete line if you want to allow user to enter characters outside the value class.
// Deleting the line would allow the user to type alpha characters, for example.
// This pretty much defeats the purpose of formatting
numberFormatter.setAllowsInvalid(false);
salaryFormattedTextField = new JFormattedTextField(formatter);
this.add(salaryFormattedTextField);
}
public static void main(String[] args)
{
Test test = new Test();
s.pack();
s.setVisible(true);
}
}
The alternative, using the code structure you already have, is to throw up a JOptionPane when the input doesn't parse correctly.
try
{
salary = Double.parseDouble(salaryTextField.getText());
restaurant.getEmployees().add(new Cook(id, name, salary));
id++;
JOptionPane cookOptionPane = new JOptionPane();
JOptionPane.showMessageDialog(cookOptionPane, "Cook added succesfully.");
}
catch(NumberFormatException ex)
{
JOptionPane cookFailPane = new JOptionPane();
JOptionPane.showMessageDialog(cookFailPane , "Could not add cook. Please enter salary using only numeric input.");
ex.printStackTrace();
}

Related

How can I create a loop to search through an object for the correct value in java?

I'm attempting to search through an object to see if a user's input matches what the program has stored, but I cannot figure out a way to make it work. I attempted to see if the value inputed by a user matched that of one in the userID spot for any of these Employee objects, but that didn't work. For example, here is the object:
Employee{userID='u1234567', userSalary=65000, userType=true}
Employee{userID='u1938562', userSalary=100000, userType=true}
Employee{userID='u1047218', userSalary=125000, userType=false}
Employee{userID='u1530078', userSalary=55000, userType=true}
Employee{userID='u1088621', userSalary=78400, userType=true}
Employee{userID='u2405234', userSalary=105000, userType=false}
Employee{userID='u1142592', userSalary=87500, userType=true}
Employee{userID='u1000092', userSalary=235000, userType=true}
Employee{userID='u1220433', userSalary=450000, userType=false}
Employee{userID='u1082304', userSalary=95000, userType=true}
My first function attempts to match the user's input with one of the userID's, but like I said it only works with the "u1234567"'s line. I have been attempting this for quite a while now, but I am relatively new to java and so I'm still learning. Below is my code, and where I commented out the "This is where I'm trying to loop through objects to look for a match" is where I would think to place this code, but I would greatly appreciate any feedback or better suggestions.
package homework4;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Arrays;
public class main {
public static void main(String[] args) throws Exception {
// pass the path to the file as a parameter
Scanner file_in = new Scanner(new File("input.txt"));
Scanner in = new Scanner(System.in);
ArrayList<Employee> employees = new ArrayList<>();
// CREATE NEW ARRAY LIST FOR THE USERS
while (file_in.hasNextLine()) {
boolean isWorker = false;
String current_line = file_in.nextLine();
String[] line_split = current_line.split(",");
if (line_split[2].equals("1")) {
isWorker = true;
}
//Load the data To the List
employees.add(new Employee(line_split[0], Integer.parseInt(line_split[1]), isWorker));
}
ArrayList<Employee> copyEmployeesList1 = new ArrayList<>();
String userID = null;
//loop 4 times then create output.txt
for(int i = 0; i < 4; i++) {
// This is where I'm trying to loop through the object to look for a match
for(int b = 0; b < employees.size(); b++) {
employees.get(userID);
}
// User inputs userID and checks to see if theres a match
System.out.println("Enter employee ID of an employee?");
userID = in.nextLine();
for (Employee employee : employees){
if (employee.getUserID().equalsIgnoreCase(userID)) {
copyEmployeesList1.add(employee);
//System.out.println(employee);
break;
} else {
System.out.println("Incorrect value, please try again");
System.out.println("Enter employee ID of an employee?");
userID = in.nextLine();
break;
}
}
// User inputs user salary and checks if it matches the previous userID's lines salary.
System.out.println("Enter salary of the employee");
String userSalary = in.nextLine();
int userInput = Integer.parseInt(userSalary);
if(userInput == copyEmployeesList1.get(0).getUserSalary()) {
} else {
System.out.println("Incorrect value, please try again");
System.out.println("Enter salary of the employee");
}
// Redundant input my professor requires, but input a 1 or a 2
System.out.println("Is this in a manager or worker? (Enter 1 for worker 2 for manager)");
String userType = in.nextLine();
boolean choice;
choice = userType.equals("1");
employees.add(new Employee(userID, Integer.parseInt(userSalary), choice));
}
//compile salaries
for(Employee emp:employees) {
ManagerEmployee.calculate(emp);
WorkerEmployee.calculate(emp);
}
employees.forEach(System.out::println);
}
employees is an arraylist of Employee, you can only use .get to get by a specific index. You will need to use something like javas stream filter or a different method like in this tutorial.
ArrayList<Employee> employeesWithASpecificID = users.stream()
.filter(employee -> employee.getUserID() == userID)
.collect(Collectors.toList());

How do I keep asking the user for input if the input wasn't a number?

I'm making a cash register with an "other" option, which allows the user to add an amount through user input. I have done this with a JOptionPane, the "other" button code is the following:
private void btnOverigActionPerformed(java.awt.event.ActionEvent evt) {
String prijs = JOptionPane.showInputDialog(this, "Vul een bedrag in");
try {
double overigePrijs = Double.parseDouble(prijs);
if (overigePrijs > 0){
aantalProducten[6]++;
totaalPerProduct[6] += overigePrijs;
}
huidigePrijsDisplay();
}
catch (Exception letter){
while (true){
prijs = JOptionPane.showInputDialog(this, "Vul a.u.b. alleen cijfers in.");
}
}
This while-loop will not close the JOptionPane, even when inputting numbers, how do I loop this correctly?
Edit after almost finishing my SE studies:
I was missing an if-statement in my while-loop. What I was trying to do was checking if the input of prijs were only numbers and if not, keep showing the dialog. I never got around to fixing this because it's an old project but I should have stated the motivation behind the code more clearly!
The question is not clear itself. What I assume that if the try part does not run as you wish, the JOptionPane should reopen and user should be prompted to do it again. If it is so, you can do the following:
Create a method:
private void doTheTask(){
String prijs = JOptionPane.showInputDialog(this, "Vul een bedrag in");
try{
//your task here.
}
catch (Exception letter){
//Call the method again.
doTheTask();
}
}
And call the method inside your action:
private void btnOverigActionPerformed(java.awt.event.ActionEvent evt){
doTheTask();
}
I suggest you a different approach in your code:
String prijs = "";
double overigePrijs = -1;
while (true) {
prijs = JOptionPane.showInputDialog(null, "Vul een bedrag in");
if (prijs != null) { // if user cancel the return will be null
try {
overigePrijs = Double.parseDouble(prijs);
break; // Exits the loop because you have a valid number
} catch (NumberFormatException ex) {
// Do nothing
}
} else {
// You can cancel here
}
// You can send a message to the user here about the invalid input
}
if (overigePrijs > 0) {
aantalProducten[6]++;
totaalPerProduct[6] += overigePrijs;
}
huidigePrijsDisplay();
This code will loop until the user enters a valid number and then you can use after the while loop. Some improvement may be necessary like a cancel logic or change the message on the second time but the main idea is this.

Simple Java currency converter errors

I am trying to create a currency converter. I have a currency table popping up as a link in my code. I want to ask the user whether or not they want to convert to U.S dollar. I think there is an error with the placement of brackets. I would love if someone could look at the program and let me know what they think :) Thank you for the help
package Testing;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.util.Scanner;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
public class Test1 {
public static JFrame f = new JFrame("HyperlinkListener");
public static void main(final String[] args) {
Scanner stdin = new Scanner(System.in); // creates new scanner
System.out.println("Hello, welcome to currency convertor"); //intro
System.out.println();
System.out.println("You will be able to convert from, and to, the U.S dollar"); //asks user what to think of what they want to convert
System.out.println("A box is going to appear, please click it and find your specific exchange rate. "); // has user go to exchange rate table
SwingUtilities.invokeLater(new Runnable() { //opens a text box that allows the user to click on a link that brings them to the website
#Override
public void run() { //runs the window to open link
Font font = new Font("Serif", Font.BOLD, 12); //picks font size and font type
JEditorPane jep = new JEditorPane();
jep.setContentType("text/html"); //set content as html
jep.setFont(font);
jep.setText(
"Click <a href='http://www.x-rates.com/table/?from=USD&amount=1'> this button </a> to see the table."); //the text that will be displayed
jep.setEditable(false); //to ensure the user can't type in the box
jep.setOpaque(true); // to ensure the box isn't see through
jep.setBackground(Color.RED); // change box color to red
jep.setSize(100, 500); //set size of link box
jep.addHyperlinkListener(new HyperlinkListener() {
#Override
public void hyperlinkUpdate(final HyperlinkEvent hle) {
if (HyperlinkEvent.EventType.ACTIVATED.equals(hle.getEventType())) {
System.out.println(hle.getURL());
Desktop desktop = Desktop.getDesktop();
try {
desktop.browse(hle.getURL().toURI());
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
});
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(jep);
f.pack();
f.setLocation(400, 200); //says where on the screen the box will be
f.setVisible(true);
}
});
boolean yes = true;
double exchangerate, currency, currencyfrom, end;
System.out.println("If you are converting to the U.S dollar, say true. If not, say false");
{
if (true) {
boolean correct = true;
do { //while loop, so the user can repeat
System.out.println("What is the currency you're converting from");
currency = stdin.nextDouble();
System.out.println("How many?");
currencyfrom = stdin.nextDouble();
System.out.println("What is the exchange rate?");
exchangerate = stdin.nextDouble();
end = currencyfrom / exchangerate;
System.out.printf("You have %d %d", end, currency);
System.out.println("Do you want to do another, say true if you do, say false if not");
yes = stdin.nextBoolean(); //if they say true, it will go through again
} while (yes);
System.out.println("Thank you for using the currency converter!"); //prints out when the user is done
}
{
if (false) {
do { //while loop, so the user can repeat
System.out.println("What is the currency you're converting to");
currency = stdin.nextDouble();
System.out.println("How many?");
currencyfrom = stdin.nextDouble();
System.out.println("What is the exchange rate?");
exchangerate = stdin.nextDouble();
end = currencyfrom * exchangerate;
System.out.printf("You have %d %d", end, currency);
System.out.println("Do you want to do another, say true if you do, say false if not");
yes = stdin.nextBoolean(); //if they say true, it will go through again
} while (correct);
}
System.out.println("Thank you for using the currency converter!"); //prints out when the user is done
}
}
}
}
Your correct variable is declared inside the if (true) block and its scope is limited to this block, it is unknown for the do-while(correct) block .
Just move this declaration outside of these blocks like you did with the yes variable.
boolean yes = true;
boolean correct = true;
double exchangerate, currency, currencyfrom, end;
....

Show an item in a JScrollPane

I store in an arraylist an object (contact) which has name,number,email.
Then i want to display lets say the name in ScrollPane but i get an error on retrieving it (from my other class).
What im doing wrong?
Heres this part of the code(i get the error in the last line using the ):
class GetUserInput implements ActionListener {
//It's the reactions to the buttons that are pressed
public void actionPerformed(ActionEvent event) {
if (event.getActionCommand().equals("Add Contact")) {
Agenda a = new Agenda();
System.out.println(event);
String inp = JOptionPane.showInputDialog("Enter your contact name");
a.setName(inp);
String inp1 = JOptionPane.showInputDialog("Enter your contact number");
a.setPhoneNumber(inp1);
String inp2 = JOptionPane.showInputDialog("Enter your contact email");
a.setEmail(inp2);
contacts.add(a);
} else if (event.getActionCommand().equals("Edit Contact")) {
String inp = JOptionPane.showInputDialog("Enter the name of the contact you wish to edit ");
} else if (event.getActionCommand().equals("Show All Contacts")) {
System.out.println(a.getName());
You can't run it, because a is created in another block. You can't access it in the last else if-block before creating and assigning a new Variable a.

ActionListener Logical Error (Java)

I have a small issue with my updateButtonResults button. I have JOptionPane Message Dialogs that are programmed to pop up when the user updates the four fields First Name, Last Name, E-mail and Sign-up date. My problem is all 4 messages pop up, even if I only update one field. Example: I update a customers last name, the message dialogs will pop up in this order (First name, Last name, E-mail, Sign-up date).
Here is my code
//method for buttons on 'resultFrame'
public void BtnAction3()
{
updateButtonResults.addActionListener(
new ActionListener()
{
//method for events that will be performed when updateButton is pressed
public void actionPerformed(ActionEvent e)
{
//instanciates variables to text in textfields
String fname = fNameTextBoxResults.getText();
String lname = lNameTextBoxResults.getText();
String email = eMailTextBoxResults.getText();
String signUpDate = signUpTextBoxResults.getText();
try
{
//statement that checks to make sure user enters only letters
if(fname.matches("[a-zA-Z]+"))
{
//updates 'Fname' field in db to text that user inputted in 'fname' textfield
rs2.updateString("Fname", fname);
JOptionPane.showMessageDialog(null, "Customer first name been updated!");
}
//statement that prompts user if they enter something other letters
else
{
JOptionPane.showMessageDialog(null, "Please enter first name in correct format!");
fNameTextBoxResults.setText("");
}
//statement that checks to make sure user enters only letters
if(lname.matches("[a-zA-Z]+"))
{
//updates 'Lname' field in db to text that user inputted in 'lname' textfield
rs2.updateString("Lname", lname);
JOptionPane.showMessageDialog(null, "Customer last name been updated!");
}
//statement that prompts user if they enter something other letters
else
{
JOptionPane.showMessageDialog(null, "Please enter last name in correct format!");
lNameTextBoxResults.setText("");
}
//statement and actions if user enters a '.'
if(email.contains("."))
{
//gets last period in "email"
int emailDotCheck = email.lastIndexOf(".");
//substring to period in variable "emailDotCheck"
String extensionCheck = email.substring(emailDotCheck);
//statement and actions if user doesn't enter email correctly
if(!email.contains("#") || !extensionCheck.matches("\\.[a-z]{3}"))
{
JOptionPane.showMessageDialog(null, "Please enter email in correct format!");
eMailTextBoxResults.setText("");
}
//statement and actions if user enters email correctly
else
{
//updates 'E-mail' field in db to text that user inputted in 'email' textfield
rs2.updateString("E_mail", email);
JOptionPane.showMessageDialog(null, "Customer E-mail been updated!");
}
}
//action if user doesnt enter email correctly
else
{
JOptionPane.showMessageDialog(null, "Please enter email in correct format!");
eMailTextBoxResults.setText("");
}
//instance variables for 'signUpDate'
int month = 100;
int day = 100;
int year = 10000;
if(signUpDate.matches("\\d{2}/\\d{2}/\\d{4}"))
{
//instance variables
String monthStr = signUpDate.substring(0,2);
String dayStr = signUpDate.substring(3,5);
String yearStr = signUpDate.substring(6);
//parsing intstance variables to Integers
month = Integer.parseInt(monthStr);
day = Integer.parseInt(dayStr);
year = Integer.parseInt(yearStr);
//statement and actions if user doesn't follow correct format
if(month > 12 || day > 31 || year > 2100)
{
JOptionPane.showMessageDialog(null, "Please enter date in correct format! (dd/MM/yyyy)");
signUpTextBoxResults.setText("");
}
//statements and actions if user enters date correctly
else
{
//updates 'Sign-up date' field in db to text that user inputted in 'signUpDate' textfield
rs2.updateString("Sign_up_date", signUpDate);
JOptionPane.showMessageDialog(null, "Customer Sign-up date been updated!");
}
}
//statement and actions if user doesn't follow correct format
else
{
JOptionPane.showMessageDialog(null, "Please enter date in correct format! (dd/MM/yyyy)");
signUpTextBoxResults.setText("");
}
//updates row in db
rs2.updateRow();
//JOptionPane.showMessageDialog(null, "Customer has been updated!");
}
catch(Exception ex)
{
}
}
});
I'm trying to learn to walk through my code, I have debugged it, but still couldn't figure the logic error out.
Thanks for any help
You have four text fields:
fNameTextBoxResults
lNameTextBoxResults
eMailTextBoxResults
signUpTextBoxResults
Rather than attempting to validate all of the input at once, let's try to make this code a little more modular. Separate all of the logic pertaining to a specific field and add it as an ActionListener to that field. Example:
fNameTextBoxResults.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
//statement that checks to make sure user enters only letters
if(fname.matches("[a-zA-Z]+"))
{
//updates 'Fname' field in db to text that user inputted in 'fname' textfield
rs2.updateString("Fname", fname);
JOptionPane.showMessageDialog(null, "Customer first name been updated!");
}
//statement that prompts user if they enter something other letters
else
{
JOptionPane.showMessageDialog(null, "Please enter first name in correct format!");
fNameTextBoxResults.setText("");
}
}
});
Rinse and repeat for the other three fields. If you have some finalizing type of action required, then you can do that with updateButtonResults. Otherwise, the button is unnecessary altogether.
Instead of using an anonymous class that extends ActionListener, you might want to define a named class that extends it, and defines a constructor by which you could pass in data such as the previous values of the text fields:
class MyActionListener extends ActionListener { // lousy name, but ...
public MyActionListener(String prevFirstName, String prevLastName, String prevEMail, String prevSignUp) {
this.prevFirstName = prevFirstName; ... and so on
}
public void ActionPerformed(ActionEvent e) {
... what you already have, except that you can say things like
if (!fname.equals(prevFirstName)) {
... now you can do your dialog and it won't show up unless the names
... are different
}
...
}
}
and then set it like this:
public void BtnAction3()
{
updateButtonResults.addActionListener(
new MyActionListener(firstName, lastName, eMail, signUp));
}

Categories