I'm trying to get an integer from a JTextField, but I keep getting a NumberFormatException. I used the code below:
JTextField price = new JTextField();
price.addActionListener(new ComboListener());
String inputText = price.getText();
int inputPrice = Integer.parseInt(inputText);
Every site says this is the proper way to do it, so I don't understand what I'm doing wrong.
edit: The full code is here:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RatePanel extends JPanel {
private double[] rate; // exchange rates
private String[] currencyName;
private JLabel result;
public RatePanel() {
currencyName = new String[]{"Select the currency..",
"European Euro", "Canadian Dollar",
"Japanese Yen", "Australian Dollar",
"Indian Rupee", "Mexican Peso"};
rate = new double[]{0.0, 1.2103, 0.7351,
0.0091, 0.6969, 0.0222, 0.0880};
JLabel title = new JLabel("How much is that in dollars?");
title.setAlignmentX(Component.CENTER_ALIGNMENT);
title.setFont(new Font("Helvetica", Font.BOLD, 20));
add(title);
add(Box.createRigidArea(new Dimension(0, 100)));
JLabel enter = new JLabel("Enter cost of item");
enter.setAlignmentX(Component.LEFT_ALIGNMENT);
enter.setFont(new Font("Helvetica", Font.BOLD, 20));
add(enter);
JTextField price = new JTextField();
price.addActionListener(new BoxListener());
price.setAlignmentX(Component.RIGHT_ALIGNMENT);
add(price);
add(Box.createRigidArea(new Dimension(0, 100)));
JLabel select = new JLabel("Select a currency: ");
select.setAlignmentX(Component.LEFT_ALIGNMENT);
select.setFont(new Font("Helvetica", Font.BOLD, 20));
add(select);
JComboBox Cbox = new JComboBox(currencyName);
Cbox.addActionListener(new ComboListener());
Cbox.setAlignmentX(Component.RIGHT_ALIGNMENT);
add(Cbox);
String index = Cbox.getSelectedItem().toString();
}
public class BoxListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String inputText = price.getText();
int inputPrice = Integer.parseInt(inputText);
}
}
public class ComboListener implements ActionListener {
public void actionPerformed(ActionEvent event, String index, double inputPrice, double[] rate) {
double finalPrice = 0;
switch (index) {
case "European Euro":
finalPrice = inputPrice * rate[1];
break;
case "Canadian Dollar":
finalPrice = inputPrice * rate[2];
break;
case "Japanese Yen":
finalPrice = inputPrice * rate[3];
break;
case "Australian Dollar":
finalPrice = inputPrice * rate[4];
break;
case "Indian Rupee":
finalPrice = inputPrice * rate[5];
break;
case "Mexican Peso":
finalPrice = inputPrice * rate[6];
break;
}
result = new JLabel(inputPrice + "USD equals " + finalPrice
+ index);
add(result);
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
I ran your code, it actually works fine (without giving me NumberFormatException).
You get NumberFormatException probably because you attempted the following:
Press Enter on the textfield when the field is empty
Press Enter on the textfield when the field contains non-numeric input
You could add validations to your input before attempting to parse the textfield's content into integer:
public class BoxListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
String s= price.getText();
if(s.matches("[0-9]+")) //Perform validation before parsing string
inputPrice = Integer.parseInt(s);
}
}
Also note that, instead of declaring inputPrice and your other components such as your textfields as local variables, I declared them as instance variables of RatePanel.
To declare your variables as instance variable instead of local variables:
class RatePanel extends JPanel{
private JTextfield txtPrice; // <--- declare here as instance variable
private int inputPrice; // <--- declare here as instance variable
public RatePanel(){
//If you declare in the constructor or other methods, they become local variables.
}
}
When I try to define it in the actionListener method, it tells me it
can't find the textbook
That is probably because you define 'price' as a local variable in the method that you create it. Your 'price' variable should be an instance variable that is visible to all methods in your class.
First of all, the code as written tries to access the text right after the text field is created, before the user has typed anything into it. The code accessing the text should be inside the action listener. If ComboListener is a class that you created, then the last two lines should be in its actionPerformed method; if you do it that way, make sure that the price variable is an instance variable or static variable (i.e., outside a method definition—whether to make it static and which class to put it in depends on how the rest of your code is structured).
An alternative way is to use an anonymous inner class, like this:
// the 'final' modifier is necessary for anonymous inner classes
// access local variables
final JTextField price = new JTextField();
price.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String inputText = price.getText();
// do the conversion and other processing here...
}
});
(I believe in newer versions of Java this can be abbreviated as
price.addActionListener((ActionEvent e) -> {
String inputText = price.getText();
// do the conversion and other processing here...
});
but I'm not 100% sure about that.)
Second, keep in mind that if you use parseInt, it'll only accept whole number values; things like 12.34 (with a decimal point) will cause an error. The simplest way to fix this is to use Double.parseDouble, although using doubles with prices can cause rounding errors, so it's not the best way to do it. Also, make sure you don't put a $ or £ or € or whatever in the box; that could also cause an error.
You are reading a JTextField immediately after creating it. At that point, it's empty empty string, which is not a valid number.
You should put that code in the listener where it will fire when the user presses Enter or something. And, additionaly, try to be nice to the user and show an error message instead of throwing an exception.
Related
So, I know there is this:
int number = Integer.parseInt("5");
String numtxt = Integer.toString(12);
double number = Double.parseDouble("4.5");
String numbertxt = Double.toString(8.2);
String letter = Character.toString('B');
char letter = "stringText".charAt(0);
so on...
but what I don't know how to make String value to call existed JButton variable name dynamically; is it even possible?
Let's say, I have 4 JButton called btn1, btn2, btn3 and btnFillNumber;
I create a String called buttonName;
package testing;
public class Testing extends javax.swing.JFrame {
String buttonName;
int num;
public Testing() {
initComponents();
}
#SuppressWarnings("unchecked")
// Generated Code <<<-----
private void btnFillNumberActionPerformed(java.awt.event.ActionEvent evt) {
for(num = 1; num <= 3; num++){
buttonName = "btn" + Integer.toString(num);
JButton.parseJButton(buttonName).setText(num);
}
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
// Look and feel stteing code (optional) <<<-----
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Testing().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton btn1;
private javax.swing.JButton btn2;
private javax.swing.JButton btn3;
private javax.swing.JButton btnFillNumber;
// End of variables declaration
}
I know there's no JButton.parseJButton(), I just don't want to make complicated explaination, I simple want a convertion from String to call JButton's variable name dynamically.
See this:
for(num = 1; num <= 3; num++){
buttonName = "btn" + Integer.toString(num);
JButton.parseJButton(buttonName).setText(num);
}
I want to make a loop using a String with
a fixed String value (btn) and
increment number after it (1, 2, 3...) and
make use to call a JButton.
I can just simply do this, but what if I got a 25 or more? So a loop what I wanted...
btn1.setText("1");
btn2.setText("2");
btn3.setText("3");
Note that the value of these JButtons are not necessarily incremental in some purpose.
Output:
My real development:
P.S. I use to make JFrame in NetBeans Design (just click and drag the objects in palette window like JPanel, JButton, etc., so I don't type the code manually except making my own logical Method; and I can't edit the code in grey background in Source View that was made automatically by Design View but in Design View itself. If you have tips and guide, I'll be happy to).
Use a Map:
private Map<String,JButton> buttonMap = new HashMap<String,JButton>();
In your constructor add your buttons:
buttonMap.add("btn1", btn1);
buttonMap.add("btn2", btn2);
buttonMap.add("btn3", btn3);
buttonMap.add("btn4", btn4);
And in your action Listener / Loop whatever make:
String buttonName = "btn1"; //should be parameter or whatever
JButton button = buttonMap.get(buttonName);
As an alternative you could just as well set up an array of JButton:
JButton[] buttons = new JButton[4];
button[0] = new JButton(); //btn1
button[1] = new JButton(); //btn2
button[2] = new JButton(); //btn3
button[3] = new JButton(); //btn4
And access it
JButton but = button[Integer.parseInt(buttonString)-1];
Or by utilizing the possibility of adding custom properties to UI elements (you'll need a JComponent for that)
getContentPane().putClientProperty("btn1", btn1);
and later retrieving whith
JButton but = (JButton)getContentPane().getClientProperty("btn1");
I agree with Kevin's comment. The best concrete Map<K,V> class is probably Hashtable<K,V>. You don't even need to create the button name, just associate an integer with it if they are all numbered (and if btnFillNumber can be 0).
Hashtable<Integer,JButton> buttonTable = new Hashtable<>();
// Fill buttonTable with buttons
JButton button = buttonTable.get(num);
if (button != null) {
// Do something with button
}
Because of autoboxing, you don't need to create Integer objects to query the hashtable, num can be an int primitive.
In my Java GUI there are 4 JTextFields. The goal is to enter default values for 3 textfields (example .8 in code below) and calculate the value and display the calculation into the 4th textfield. The user should then be able to change the values of the numbers within the JTextField and then press the calculate button again to get the new values to recalculate and display them.
Problem: when the JTextfields are edited and the calculate button is pressed it does not calculate with the new numbers but instead with the old initial values.
JTextField S = new JTextField();
S.setText(".8");
String Stext = S.getText();
final double Snumber = Double.parseDouble(Stext);
.... *same setup for Rnumber*
.... *same setup for Anumber*
....
JButton btnCalculate_1 = new JButton("Calculate");
btnCalculate_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
int valuec = (int) Math.ceil(((Snumber*Rnumber)/Anumber)/8);
String stringValuec = String.valueOf(valuec);
NewTextField.setText(stringCalc);
}
I have checked several posts and tried:
How Do I Get User Input from a TextField and Convert it to a Double?
Using JTextField for user input
for the basics. However whenever trying to adapt it to my code eclipse returns various errors.
use S.getText() inside the actionPerformed() method.
The code inside actionperformed block is invoked on the button press and the code outside it remains unaffected.
So once you run your code and insert values to text fields, it assigns the a value but it does not change the same when you change the value and press calculate button
try using This code.
class a extends JFrame implements ActionListener
{
JTextField t1,t2,t3;
a()
{
setLayout(null);
t1 = new JTextField();
t2 = new JTextField();
t3 = new JTextField();
JButton B1 = new JButton("Calculate");
t3.setEditable(false);
t1.setBounds(10,10,100,30);
t2.setBounds(10,40,100,30);
t3.setBounds(10,70,100,30);
B1.setBounds(50, 110, 80, 50);
add(t1);
add(t2);
add(t3);
add(B1);
B1.addActionListener(this);
setSize(200,200);
setVisible(true);
}
public static void main(String args[])
{
new a();
}
#Override
public void actionPerformed(ActionEvent e)
{
double Snumber = Double.parseDouble(t1.getText());
double Rnumber = Double.parseDouble(t2.getText());
double Anumber = Snumber+Rnumber;
t3.setText(String.valueOf(Anumber));
}
}
I'm trying to create a Java AWT program with these codes:
import javax.swing.*;
import java.awt.*;
public class Exer1 extends JFrame {
public Exer1(){
super ("Addition");
JLabel add1 = new JLabel("Enter 1st Integer: ");
JTextField jtf1 = new JTextField(10);
JLabel add2 = new JLabel("Enter 2nd Integer: ");
JTextField jtf2 = new JTextField(10);
JButton calculate = new JButton("Calculate");
FlowLayout flo = new FlowLayout();
setLayout(flo);
add(add1);
add(jtf1);
add(add2);
add(jtf2);
add(calculate);
setSize(200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] a){
Exer1 ex1 = new Exer1();
}
}
My problem is HOW to add these 2 integers using JTextField. Can someone help me? Thank you so much. :)
You need to use ActionListener on your JButton.
Then you need to get int's from JTextField's and sum them like next:
calculate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
int i1 = Integer.valueOf(jtf1.getText());
int i2 = Integer.valueOf(jtf2.getText());
System.out.println("sum=" + (i1 + i2));
} catch (Exception e1){
e1.printStackTrace();
}
}
});
Generally, you should create an event listener for click events on your button: Lesson: Writing Event Listeners. In that handler, you would take contents of your two text fields, convert them to integers:
Integer i1 = Integer.valueOf(jtf1.getText());
Then you can add those two integers and display them in another control or do anything else with them.
Start with How to Use Buttons, Check Boxes, and Radio Buttons and
How to Write an Action Listeners
This will provide you with the information you need to be able to tell when the user presses the button.
JTextField#getText then return's String. The problem then becomes a problem of converting a String to a int, which if you take the time, there are thousands of examples demonstrating how to achieve that
Once you've played around with oddities of converting String to a int, you could take a look at How to Use Spinners and How to Use Formatted Text Fields which perform there own validation on the values been entered
I am attempting to get the next set of values to display in the JTextFields after hitting the next button. I am new to programming so I am not really sure what I am missing. What I want to occur is when I hit the next button when the window displays the next set of values will now display in the appropriate JTextFields unfortunately what ends up happening is nothing. I have tried several different ways of getting this to work and so far nothing. I know it is not the button its self because if I change the actionPerformed next to say setTitle(“5000”) it will change the title within the window. Any help is appreciated.
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import java.util.Arrays;
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame implements ActionListener {
JButton next;
JButton previous;
JButton first;
JButton last;
private JLabel itmNum = new JLabel("Item Number: ", SwingConstants.RIGHT);
private JTextField itemNumber;
private JLabel proNm = new JLabel ("Product Name: ", SwingConstants.RIGHT);
private JTextField prodName;
private JLabel yr = new JLabel("Year Made: ", SwingConstants.RIGHT);
private JTextField year;
private JLabel unNum = new JLabel("Unit Number: ", SwingConstants.RIGHT);
private JTextField unitNumber;
private JLabel prodPrice = new JLabel("Product Price: ", SwingConstants.RIGHT);
private JTextField price;
private JLabel restkFee = new JLabel("Restocking Fee", SwingConstants.RIGHT);
private JTextField rsFee;
private JLabel prodInValue = new JLabel("Product Inventory Value", SwingConstants.RIGHT);
private JTextField prodValue;
private JLabel totalValue = new JLabel("Total Value of All Products", SwingConstants.RIGHT);
private JTextField tValue;
private double toValue;
int nb = 0;
char x = 'y';
public GUI()
{
super ("Inventory Program Part 5");
setSize(800,800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLookAndFeel();
first = new JButton("First");
previous = new JButton("Previous");
next = new JButton("Next");
last = new JButton("Last");
first.addActionListener(this);
previous.addActionListener(this);
next.addActionListener(this);
last.addActionListener(this);
Movies[] titles = new Movies[9];
titles [0] = new Movies(10001, "King Arthur", 25 , 9.99, 2004, .05);
titles [1] = new Movies(10002,"Tron", 25, 7.99, 1982, .05);
titles [2] = new Movies(10003, "Tron: Legacy",25,24.99,2010,.05);
titles [3] = new Movies(10004,"Braveheart", 25,2.50,1995,.05);
titles [4] = new Movies(10005,"Gladiator",25,2.50,2000,.05);
titles [5] = new Movies(10006,"CaddyShack SE",25,19.99,1980,.05);
titles [6] = new Movies (10007,"Hackers",25,12.50,1995,.05);
titles [7] = new Movies (10008,"Die Hard Trilogy",25,19.99,1988,.05);
titles [8] = new Movies (10009,"Terminator",25,4.99,1984,.05);
Arrays.sort (titles, DVD.prodNameComparator);
itemNumber.setText(Double.toString(titles[nb].getitemNum()));
prodName.setText(titles[nb].getprodName());
year.setText(Integer.toString(titles[nb].getYear()));
unitNumber.setText(Integer.toString(titles[nb].getunitNum()));
price.setText(Float.toString(titles[nb].getprice()));
rsFee.setText(Double.toString(titles[nb].getRestkFee()));
prodValue.setText(Double.toString(titles[nb].getprodValue()));
tValue.setText("2636");
setLayout(new GridLayout(8,4));
add(itmNum);
add(itemNumber);
add(proNm);
add(prodName);
add(yr);
add(year);
add(unNum);
add(unitNumber);
add(prodPrice);
add(price);
add(restkFee);
add(rsFee);
add(prodInValue);
add(prodValue);
add(totalValue);
add(tValue);
add(first);
add(previous);
add(next);
add(last);
setLookAndFeel();
setVisible(true);
}
public void updateFields()
{
itemNumber.getText();
prodName.getText();
year.getText();
unitNumber.getText();
price.getText();
rsFee.getText();
prodValue.getText();
tValue.getText();
}
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
if (source == next)
{
nb++;
}
}
private void setLookAndFeel()
{
try{
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
System.err.println("couln't use the system"+ "look and feel: " + e);
}
}
}
Your ActionListener only has one assignment
nb = 1;
and a repaint. This does not update the JTextFields with the values from your Movies array titles. You need to do this explicitly.
itemNumber.setText(Double.toString(titles[nb].getItemNum()));
...
To make this possible, you will need to make your Movies titles array a class member variable so that it can be accessed from your ActionListener.
Also you never actually change the value of nb in your ActionListener. As it's a "next" button, you will probably want to increment it:
nb++;
Side Notes:
Java uses camelcase which would make the method getitemNum getItemNum.
An ArrayList would give you more flexibility for adding Movie titles over an array which is fixed in size.
I think the logic of chaning JTextFields is inside the constructor of GUI class. So unless you are creating another object of GUI class, which I can see it is not being created. Your JTextFields will not be updated.
So basically to solve this problem you will have to move your logic of changing JTextFields inside another method like for example
public void updateFields(){
//place your logic code here
}
and then from actionPerformed method call this updateFields() method
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
if (source == next)
{
nb =1;
}
updateFields();
///repaint(); /// you don't need the repaint method
}
As per your question in the comments and as far as my understanding is concerned place your titles array outside the constructor, and do the following changes so it will look something like this:
private JTextField tValue;
private double toValue;
int nb = 0; //note initialize this to 0
Movies[] titles = new Movies[9];//this is the line that comes out of the Constructor
public GUI()
{
///inside the constructor do the following changes
for (int i = 0; i < titles.length; i ++)
{
toValue += (titles[i].gettotalVal());
}
//note I will be accessing the 0th position of the array assuming you need the contents of the first objects to be displayed
itemNumber = new JTextField(Double.toString(titles[0].getitemNum()));
prodName = new JTextField(titles[0].getprodName());
year = new JTextField(Integer.toString(titles[0].getYear()));
unitNumber = new JTextField (Integer.toString(titles[0].getunitNum()));
price = new JTextField (Float.toString(titles[0].getprice()));
rsFee = new JTextField (Double.toString(titles[0].getRestkFee()));
prodValue = new JTextField(Double.toString(titles[0].getprodValue()));
tValue = new JTextField ("2636");
nb = 0;
//if (nb == 0) you don't need a if statement
//{
next.addActionListener(this);
//}
///Now for the updateFields() method
public updateFields(){
nb++;
itemNumber.setText(Double.toString(titles[nb].getitemNum());
prodName.setText(titles[nb].getprodName());
year.setText(Integer.toString(titles[nb].getYear()));
unitNumber.setText(Integer.toString(titles[nb].getunitNum()));
price.setText(titles[nb].getprice()));
rsFee.setText(Double.toString(titles[nb].getRestkFee()));
prodValue.setText(Double.toString(titles[nb].getprodValue()));
}
My assignment is to input 20 numbers via a text field then out the mean, the median and the total using a while loop. I should be able to figure out the while loop myself, but I can't get the text field to input numbers into an array. Please help, here is my code so far:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
public class whileloopq extends Applet implements ActionListener
{
Label label;
TextField input;
int[] numArray = new int[20];
int num;
public void init ()
{
Label label = new Label("Enter numbers");
TextField input = new TextField(5);
add(label);
add(input);
input.addActionListener(this);
}
public void actionPerformed (ActionEvent ev)
{
int num = Integer.parseInt(input.getText());
int index = 0;
numArray[index] = num;
index++;
input.setText("");
}
public void paint (Graphics graf)
{
graf.drawString("Array" + numArray, 25, 85);
}
}
Any help would be much appreciated.
(Answer written under the assumption that this is a homework assignment.)
You know how to parse an integer from a string, as you show with your usage of Integer.parseInt, but you are calling it to parse the entire 20 characters as one integer. You need to get each character individually to be parsed.
I recommend using a for loop, and String#substring to substring the input text into several strings of length one.
Alternatively, you can split the input text around an empty string and then iterate through the resulting array (note that the first string in the array will be empty), but the other approach is more likely the one expected from someone new to Java, so you'll have to use your judgement here.
In actionPerformed() you are trying to read from class filed input.setText("");
but in init() you didn't initialized that field but created and added to applet local variable
TextField input = new TextField(5);
so class field is steal null. Change it to
input = new TextField(5);
import java.awt.*;
public class frame4array extends Frame
{
Checkbox c1[];
TextField t1[];
int i;
frame4array(String p)
{
super(p);
c1=new Checkbox[2];
t1=new TextField[2];
for(i=0;i<2;i++)
{
t1[0]=new TextField();
t1[0].setBounds(200, 50, 150, 30);
t1[1]=new TextField();
t1[1].setBounds(200, 80, 150, 30);
c1[0]=new Checkbox("Singing");
c1[0].setBackground(Color.red);
c1[0].setBounds(430,200,120,40);
c1[1]=new Checkbox("Cricket",true);
}
for(i=0;i<2;i++)
{
add(t1[i]);
add(c1[i]);
}
setFont(new Font("Arial",Font.ITALIC,40));
}
public static void main(String s[])
{
frame4array f1=new frame4array("hello");
f1.setSize(600,500);
f1.setVisible(true);
}
}