How to access user input in a JTextField? - java

For a school project I am writing a program where I need to retrieve user input from a JTextField. I've tried using the getText() method, but it is returning an empty string error.
String s = input.getText();
if(changeNum.equals("")){
firstNum = s;
}
if(!changeNum.equals("")){
secondNum = s;
}
firstNum and secondNum are both strings. The error that is being returned is:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: empty String
It's being returned at this line:
Double firstN = Double.parseDouble(firstNum);
What do I do? Thank you!
Edit: Forgot to add that input is the name of my JTextField, in case that is confusing.

Change all your varibles to double (firstNum etc.) and change your code like :
Note : if you not using negatIive numbers
double s = null;
try{
s = Double.parseDouble(input.getText());
}catch(NumberF... e){e.getMesssge();}
if(s > 0){
if(changeNum >= 0){
firstNum = s;
}
else {
secondNum = s;
}
}
//if you have to convert it to String use :
String str =String.valueOf(your double variable);

This is how I like to do it (in a general sense). Let's say I have a panel with three text boxes and I want to get the value of each one (each represents a different type). This is what I'd do:
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.BoxLayout;
public class Panel extends JPanel
{
JTextField textBox;
JTextField intBox;
JTextField floatBox;
JTextField dblBox;
public Panel()
{
textBox = new JTextField("Hello");
intBox = new JTextField("10");
floatBox = new JTextField("3");
dblBox = new JTextField("3.14");
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(textBox);
this.add(intBox);
this.add(floatBox);
this.add(dblBox);
}
public String getText()
{
return textBox.getText();
}
public int getInt()
{
try
{
return Integer.parseInt( intBox.getText() );
}
catch(NumberFormatException execp) { }
return -1;
}
public float getFloat()
{
try
{
return Float.parseFloat( floatBox.getText() );
}
catch(NumberFormatException execp) { }
return -2.0f;
}
public double getDouble()
{
try
{
return Double.parseDouble( dblBox.getText() );
}
catch(NumberFormatException execp) { }
return -2.0;
}
}
Another option is to make Panel implement ActionListener, and dblBox.addActionListener(this). Then you can get your JTextField to call a method from your parent whenever you change a number, parse the data, and write error messages in a JLabel if the casting throws an exception, or to private members if it succeeded. Then use getters to read the private members.

Related

Java Input Validation

So I am working with a program that is supposed to incorporate try-catch blocks for exception handling. What I can't figure out is how to write a simple if statement for checking input from the user via Scanner to make sure it is a double and not a letter or a character so that if it is the program will catch it, display the error message, and tell the user to re-enter another value until a suitable input is entered. What I am looking for is a simple if(_width equals a letter/character) then return false along with an error message to go along with my already present if statement that checks whether the input is greater than zero.
my current code is below:
public class Rectangle {
//two double data fields width and height, default values are 1 for both.
private double width = 1;
private double height = 1;
private String errorMessage = "";
//no-arg constructor creates default rectangle
public Rectangle() {
}
//fpzc, called by another program with a statement like Rectangle rec = new Rectangle(#, #);
public Rectangle (double _width, double _height) throws Exception {
setWidth(_width);
setHeight(_height);
}
//get functions
public double getArea(){
return (width * height);
}
public double getPerimeter() {
return (2*(width + height));
}
public String getErrorMessage() {
return errorMessage;
}
//set functions
public void setWidth(double _width) throws Exception {
if( !isValidWidth(_width)){
Exception e = new Exception(errorMessage);
throw e;
//System.out.println(errorMessage);
//return false;
}
width = _width;
}
public void setHeight(double _height) throws Exception {
if ( !isValidHeight(_height)){
Exception e = new Exception(errorMessage);
throw e;
//System.out.println(errorMessage);
//return false;
}
height = _height;
}
//isValid methods
public boolean isValidWidth(double _width) {
if(_width > 0){
return true;
}
else {
errorMessage = "Invalid value for width, must be greater than zero";
return false;
}
if ()
}
public boolean isValidHeight(double _height) {
if(_height > 0){
return true;
}
else {
errorMessage = "Invalid value for height, must be greater than zero";
return false;
}
}
}
My class is being called by another test program that i have written correctly. Any help is appreciated! Thank you.
maybe something like:
String errorMessage = "error";
Scanner in = new Scanner(System.in);
String str = in.nextLine();
try {
Double.parseDouble(str);
}
catch( Exception e ){
System.out.println(errorMessage);
}
or iterate through the input and check if each character is digit:
String errorMessage = "error";
Scanner in = new Scanner(System.in);
String str = in.nextLine();
for(int i=0;i<str.length();i++){
char token = str.charAt(i);
if(!Character.isDigit(token) && token!='.' ) {
System.out.println(token + " doesnt work");
break;
}
}
On declaring your scanner you could also:
double num;
String errorMessage = "error";
while(true) {
Scanner in = new Scanner(System.in);
if (in.hasNextDouble()) {
num = in.nextDouble();
System.out.println(num);
break;
}
else System.out.println(errorMessage);
}
Maybe this code helps you:
double Input=0;
while(!(Input > 0)){{
System.out.println("Enter Valid Number");
Input = new Scanner(System.in).nextDouble();
}

show warning if users enter letter instead number in java applet

I am writing an tip calculator app in java applet with GUI, my question is how I make sure the error message will pop up if users enter letter instead of number
it is my first time asking question, please be easy on me! Thanks!!!
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// Typing in the text field and hitting return adds text to text area.
// Clicking on button erases the text area.
public class TextApplet extends Controller implements ActionListener
{
private static final int ROWS = 1; // rows in TextArea
private static final int COLS = 10; // cols in text field & area
private String amount;
private float number;
private JTextField inField, output; // Input field
private JButton clear, calc;
// button to clear output
public void begin()
{
Container contentPane = getContentPane();
JPanel topPanel = new JPanel(); // prepare text field & label
JLabel inLabel = new JLabel("Bill Cost: ");
inField = new JTextField(COLS);
inField.addActionListener(this);
JLabel topTitle = new JLabel("Tip Calculator", JLabel.CENTER);
JPanel combinePanel = new JPanel();
combinePanel.add ( inLabel );
combinePanel.add ( inField );
JPanel combinePanel1 = new JPanel();
combinePanel1.add ( topTitle );
topPanel.add ( combinePanel1 );
topPanel.add ( combinePanel );
topPanel.setLayout ( new GridLayout ( 3,1) );
contentPane.add(topPanel,BorderLayout.NORTH);
JPanel centerPanel = new JPanel(); // prepare text area & label
JLabel outLabel = new JLabel("Bill + Tip:");
output = new JTextField(COLS);
output.setEditable(false); // Prevent user from wrting in output
centerPanel.add(outLabel);
centerPanel.add(output);
contentPane.add(centerPanel,BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
// create button
clear = new JButton(" Clear ");
calc = new JButton("Calculate");
calc.addActionListener(this);
clear.addActionListener(this);
bottomPanel.add(calc);
bottomPanel.add(clear);
contentPane.add(bottomPanel,BorderLayout.SOUTH);
validate();
}
// add text to area if user hits return, else erase text area
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
}
There are any number of ways you might achieve this, you could use
An InputVerifier
A JFormattedTextField
A JSpinner
Or a DocumentFilter and examples
Take a look at javax.swing.InputVerifier. That can be easily attached to a JTextField
JTextField inputField = new JTextField();
inputField.setInputVerifier(new NumericInputVerifier());
private class NumericInputVerifier extends InputVerifier
{
#Override
public boolean verify(JComponent input)
{
if (((JTextField) input).getText().matches("[0-9]+"))
{
return true;
}
else
{
JOptionPane.showMessageDialog(input, "Only numbers are allowed", "Warning", JOptionPane.WARNING_MESSAGE);
return false;
}
}
}
A complete example can be found here.
Edit Added an example of how to use InputVerifier to limit to numeric input. You'll want to double check the regex, but the basic idea is there...
Use a JFormattedTextField or a DocumentFilter. Then the user won't even be able to enter a non-numeric digit. See:
How to Use Formatted Text Fields
Implementing a Document Filter
For the document filter you will need to check each chraacter as it is entered to make sure it is a digit.
It is always better to do simple edits like that as the user types, rather than wait until you click on a button to do processing.
Hello Friend I will give a suggestion
please add validation when call actionPerformed method
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
if(validate()){
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else{
// show message for inter valid number or any other
}
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
boolean validate(){
try{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
return true;
}
catch(Exception e){
return false;
}
}
If you try to call Float.parseFloat on a String that cannot be converted to a float, it will throw a NumberFormatException. You need to catch this exception.
try {
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
} catch(NumberFormatException e) {
//code to show error message here
}
Well considering, you'd have to turn the string into an integer to do the math, you could do this:
try {
int number = Ineger.parseInt(inField.getText());
} catch (NumberFormatException e) {
//SHOW WARNING
}
if (Label1.getText().matches("[0-9]+"))
// does Label1 containts numbers.
{
// do math
}
else
{
// warning
Lavbel1.setText("");
}

Converting JTextField to an int array with exceptions

So I've been trying to figure this out but to no avail. I have to convert JTextField to an int array while having two exceptions, NumberFormatException, and ArrayIndexOutOfBoundsException. I was able to find a method to convert it, but it wont throw the NumberFormatException when I enter letters.
try {
int j=0;
String str = "" + numbersField.getText();
char digit[] = str.toCharArray();
for (int i=0; i<digit.length; i++) {
if (Character.isDigit(digit[i])) {
array[j]=Character.getNumericValue(digit[i]);
System.out.print(array[j] + " "); //Checking if it works
++j;
}
}
} catch (NumberFormatException e1) {
System.err.println("NumberFormatException: Array can only hold integers");
} catch (ArrayIndexOutOfBoundsException e1) {
System.err.println("ArrayIndexOutOfBoundsException: Array can only hold up to 10 elements");
}
Personally, I believe it's not throwing the NumberFormatException because it converts JTextField to char, but I could be totally wrong. Any help is appreciated.
EDIT: I only included part of the program since it's kinda lengthy in my opinion. Array is initialized way before this. The ultimate goal of this portion of the program is to have the user input a limit of 10 numbers while throwing an exception if a letter is inputted or if it exceeds 10 numbers. This is my first time using exceptions so I'm still relatively new to it, so please excuse me for any mistakes I've done.
You can check if whole text has only digits, then convert text to int and then put all digits to array.
Try an alternative:
String str = numbersField.getText();
try {
int value = Integer.parseInt(str);
int[] array = new int[str.lenght - 1];
j = array.length - 1;
while (value > 0) {
array[j] = value % 10;
value /= 10;
--j;
}
} catch (NumberFormatException ex) {
System.out.println("Enter only digits!")
}
UPD: also you need to check if value < 0 and show an error (if you don't accept minus sign) and use str.trim() before converting to int
Hmmm well maybe this could help, maybe not the most efficient but does its job:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class JTextFieldIntToArrayValidation extends JFrame {
private int[] integerArray;
private JButton button;
private JTextField tf;
public JTextFieldIntToArrayValidation() {
createAndShowUI();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JTextFieldIntToArrayValidation test = new JTextFieldIntToArrayValidation();
test.setVisible(true);
}
});
}
private void createAndShowUI() {
setTitle("Converting JTextField to an int array with exceptions");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
addComponentsToPane();
addListeners();
pack();
tf.grabFocus();
}
private void addComponentsToPane() {
button = new JButton("Convert JTextfield to array");
tf = new JTextField(10);
getContentPane().add(tf, BorderLayout.EAST);
getContentPane().add(button, BorderLayout.WEST);
}
private void addListeners() {
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
String tmp = tf.getText();
char[] chars = tmp.toCharArray();
integerArray = new int[chars.length];
try {
if (integerArray.length > 10) {//if digits entered are greater then 10. This however only allows for single digits!!!
throw new ArrayIndexOutOfBoundsException("Array cannot be larger then 10: " + integerArray.length);
}
for (int i = 0; i < tmp.length(); i++) {
if (!Character.isLetter(chars[i])) {//if its not a letter
integerArray[i] = Integer.parseInt(chars[i] + "");//stops java handling chars as ints
} else {//its a letter
throw new NumberFormatException("Only valid integers must be entered no letters: " + chars[i]);
}
}
printArray();
} catch (NumberFormatException | ArrayIndexOutOfBoundsException ex) {
JOptionPane.showMessageDialog(getContentPane(), ex.getMessage());
}
}
});
}
private void printArray() {
for (int i : integerArray) {
System.out.println(i);
}
}
}

Counting the number of words in a text area

Hello everyone my first question on stack overflow
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
public class TI extends JFrame implements ActionListener
{
static int count=0;
String ct;
JTextField word;
JTextArea tohide;
public static void main(String arg[])
{
TI ti=new TI();
}
public TI()
{
JPanel j=new JPanel();
JLabel def=new JLabel("Enter the text to be encrypted");
word=new JTextField("",20);
tohide=new JTextArea("",5,20);
JButton jb=new JButton("COUNT");
tohide.setBorder(BorderFactory.createLoweredBevelBorder());
j.add(def);
j.add(tohide);
j.add(word);
j.add(jb);
add(j);
setSize(500,500);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
jb.addActionListener(this);
}
public void actionPerformed(ActionEvent ae)
{
String txt=tohide.getText();
StringTokenizer stk=new StringTokenizer(txt," ");
while(stk.hasMoreTokens())
{
String token=stk.nextToken();
count++;
}
ct=Integer.toString(count);;
word.setText(ct);
}
}
I want to count the number of words that are being typed in the textarea.There is a logical error.As I keep clicking the count button the word count increases.
You never reset the count to 0 before recalculating the number of words. There doesn't seem to be a need for count to be a class variable. Making that change would make this kind of mistake impossible.
Use javax.swing.text.Utilities which has
public static final int getWordStart(JTextComponent c, int offs)
public static final int getWordEnd(JTextComponent c, int offs)
Separating by spaces is not enough. The separator could be also tab, \n etc. chars
public void actionPerformed(ActionEvent ae) {
word.setText(String.valueOf(tohide.getText().split("\\s").length));
}
I am using the following code to do the task. The idea behind it is that each pair of words is separated by a space. hence using space to split seems straight forward. if words contain carriage return, then, replacing the carriage return with empty string has to be done before counting. I hope that it helps
public int WordCount(String Words){
//Initiate Result
String s = Words+" "; //Add space after the received string
String result ="";
int i = 0;
int count = s.length();
try {
for (i = 0; i <= count - 1; i++) {
if (count - i > 1) {
String tempString = s.substring(0, s.indexOf(" "));
if (s.contains(" ") && (!s.isEmpty())) {
s = s.substring(s.indexOf(" ") + 1, s.length());
//get substring between " " and lenght ;
} else {
if(!s.isEmpty()) {
//output nothing
}
}
} else {
//output nothing;
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
return i;
}

How do I switch the end function?

As in, the value as the end where it says "X dollars converts to Y russian ruble" (after the two Digits new Decimal Format) - the problem is that it can be russian ruble, british pound, or euro. How can I differentiate? (text inserted at line in question)
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.DecimalFormat;
public class CurrencyConversion extends Applet implements ItemListener
{
//declare variables and color
double dollars, answer;
int empCode;
Image dollarSign;
Color darkRed = new Color(160, 50, 0);
//Create components for applet
Label promptLabel = new Label("Enter the dollar amount (do not use commas or dollar signs):");
TextField currencyField = new TextField(20);
Label codeLabel = new Label ("Select the desired currency:");
CheckboxGroup codeGroup = new CheckboxGroup () ;
Checkbox britishpoundBox = new Checkbox("British Pound",false,codeGroup);
Checkbox euroBox = new Checkbox("Euro",false,codeGroup);
Checkbox russianrubleBox = new Checkbox("Russian Ruble",false,codeGroup);
Checkbox hiddenBox = new Checkbox("",true,codeGroup);
Label outputLabel = new Label("Click an option to convert the desired currency.");
public void init()
{
setBackground(darkRed);
setForeground(Color.white);
add(promptLabel);
add(currencyField);
currencyField.requestFocus();
currencyField.setForeground(Color.black);
add(codeLabel);
add(britishpoundBox);
britishpoundBox.addItemListener(this);
add(euroBox);
euroBox.addItemListener(this);
add(russianrubleBox);
russianrubleBox.addItemListener(this);
add(outputLabel);
}
//This method is triggered by click
public void itemStateChanged(ItemEvent choice)
{
try
{
dollars = getCurrency();
empCode = getCode();
answer = getComm(dollars,empCode);
output(answer, dollars);
}
catch (NumberFormatException e)
{
outputLabel.setText("You must enter a dollar amount greater than zero.");
hiddenBox.setState(true);
currencyField.setText("");
currencyField.requestFocus();
}
}
public double getCurrency()
{
double currency = Double.parseDouble(currencyField.getText());
if (currency <= 0) throw new NumberFormatException();
return currency;
}
public int getCode()
{
int code = 0;
if (britishpoundBox.getState()) code = 1;
else
if (euroBox.getState()) code = 2;
else
if (russianrubleBox.getState()) code = 3;
return code;
}
public double getComm(double currency, int code)
{
double amount = 0.0;
switch(code)
{
case 1:
amount = .79610 * currency;
break;
case 2:
amount = .70880 * currency;
break;
case 3:
amount = 35.88240 * currency;
break;
}
return amount;
}
public void output(double amount, double currency)
{
DecimalFormat twoDigits = new DecimalFormat("##.00");
outputLabel.setText("Your amount of " + twoDigits.format(currency) + " dollars converts to " + twoDigits.format(amount) RIGHT HERE - what do I do? );
}
public void paint(Graphics g)
{
dollarSign = getImage(getDocumentBase(), "dollarsign.gif");
g.drawImage(dollarSign,12,28,this);
}
}
Create a mapping from Integer to String, populate it with the various currency descriptions, and pass the Integer to the output function so that you can get the description from the mapping.
Wrap the currency concept into its own object. Override the ToString() method and return the name of the currency or define an explicit property to return the currency type. Pass the currency object around instead of the not so complex double and make the rate which was previously the double a property on the object.
I'd suggest you to use class java.util.Currency. The exchange rate of each currency should not be hard coded. For first phase just put it into properties file, i.e.:
RUB=35.88240
GBP=.79610
Avoid using hard coded list of currencies. Instead parse this property file, extract all keys, then use Currency.getInstance(currencyCode). Both UI and logic will be generic. Your application will be at least twice shorter and much more flexible.

Categories