I'm trying to write a code for my CS 1 class.
The point of the code is to write a code where you are making change out of a hundred dollar bill out for what ever amount, I need to give back the appropriate bills and coins.
I have to write the JFrame manually
It would be helpful if someone could show me where I'm going wrong in the computation.
/**
*
* #author esamayoa
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GetChange extends JFrame {
//Declare variables
JButton bCompute, bReset;
JTextField tAmount, tQuarters, tDimes, tNickels, tPennies, tTwenty, tTen, tFive, tOne;
JLabel lAmount, lQuarters, lDimes, lNickels, lPennies, lTwenty, lTen, lFive, lOne;
double amount, diff, totalPaid, quarter, dime, nickel, penny, twenty, ten, five, one;
public GetChange (){
//Set the attributes of the Jframe
setTitle("Eric");
setLocation(500,10);
setSize(450,1000);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setVisible(true);
//Create your Gui components
lAmount = new JLabel("Amount");
lQuarters = new JLabel("Quarters:");
lDimes = new JLabel("Dimes:");
lNickels = new JLabel("Nickels:");
lPennies = new JLabel("Pennies:");
lTwenty = new JLabel("Twenties");
lTen = new JLabel("Tens");
lFive = new JLabel("Fives");
lOne = new JLabel("Ones");
tAmount = new JTextField();
tQuarters = new JTextField();
tDimes = new JTextField();
tNickels = new JTextField();
tPennies = new JTextField();
tTwenty = new JTextField();
tTen = new JTextField();
tFive = new JTextField();
tOne = new JTextField();
bReset = new JButton("Reset");
bCompute = new JButton("Compute");
//Add you Gui components to the Jframe
setLayout(new GridLayout(10,2));
add(lAmount);
add(tAmount);
add(lQuarters);
add(tQuarters);
add(lDimes);
add(tDimes);
add(lNickels);
add(tNickels);
add(lPennies);
add(tPennies);
add(lTwenty);
add(tTwenty);
add(lTen);
add(tTen);
add(lFive);
add(tFive);
add(lOne);
add(tOne);
add(bCompute);
add(bReset);
//Updates frame
this.validate();
//Add Action Listeners to buttons
bReset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
tAmount.setText("");
tQuarters.setText("");
tDimes.setText("");
tNickels.setText("");
tPennies.setText("");
tTwenty.setText("");
tTen.setText("");
tFive.setText("");
tOne.setText("");
tAmount.setText("");
}
});
//Create computation for compute button
bCompute.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
totalPaid = 100;
amount = Double.parseDouble(tAmount.getText());
diff = totalPaid-amount;
twenty = diff/20;
diff = diff%20;
tTwenty.setText(""+ twenty);
ten = diff/10;
diff = diff%10;
tTen.setText(""+ ten);
five = diff/5;
diff = diff%5;
tFive.setText(""+ five);
one = diff/1;
diff = diff%1;
tOne.setText(""+ one);
quarter = diff/.25;
diff = diff%.25;
tQuarters.setText(""+ quarter);
dime = diff/.1;
diff = diff%.1;
tDimes.setText(""+ dime);
nickel = diff/.05;
diff = diff%.05;
tNickels.setText(""+ nickel);
penny = diff/.01;
diff = diff%.01;
tPennies.setText(""+ penny);
}
});
}
//Main Method
public static void main(String[] args) {
// TODO code application logic here
GetChange myApp = new GetChange();
}
}
To Solve the First problem(Frame not showing) insert the following after all components are added,
this.validate(); // updates frame
To add implementation to the reset button, just use .setText("");
bReset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
tAmount.setText("");
tQuarters.setText("");
tDimes.setText("");
tNickels.setText("");
tPennies.setText("");
tTwenty.setText("");
tTen.setText("");
tFive.setText("");
tOne.setText("");
tResult.setText("");
}
});
To add implementation to the Compute Button...
bCompute.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
double Amount = Double.parseDouble(tAmount.getText());
double q = (double) Integer.parseInt(tQuarters.getText()) *.25;
double d = (double) Integer.parseInt(tDimes.getText()) *.10;
double n = (double) Integer.parseInt(tNickels.getText()) *.05;
double p = (double) Integer.parseInt(tPennies.getText()) *.01;
double T = (double) Integer.parseInt(tTwenty.getText()) *20;
double Ten = (double) Integer.parseInt(tTen.getText()) *10;
double Five = (double) Integer.parseInt(tFive.getText()) *5;
double one = (double) Integer.parseInt(tOne.getText()) *1;
double TotalPaid = q+d+n+p+T+Ten+Five+1;
double diff = TotalPaid-Amount;
//Heres an example to create how many twenties you need
int totalTwenties = (int)diff /20;
diff = diff%20;
tTwenty.setText("" + totalTwenties);
}
});
Basically, I got the difference between Amount paid and Amount Cost.
A) Then, the number of times a 20 can fit into the difference is found by /20. Next, I modulus or found the remainder of the difference and twenty.
B) To Find the number of other coins/bills that you need to give as change, repeat the process described in A.
Related
My program contains a label with the caption “Choose a coffee” and four check boxes – Americano, Espresso, Double Espresso and Latte. Note: A JCheckBox array is recommended here)
I need to add event handling code to allow the user to purchase one or more items. The bill amount is displayed in a label after the user has made their selections.
The prices are Americano €3.75, Espresso €4.00, Double Espresso €4.50 and Latte €3.50. An array is suitable here also.
As the user makes a choice a label is displayed showing the bill.
I cant figure out how to add the cost when the check box is selected and remove the cost when it is de selected using the arrays.
Any help appreciated.
This is my code so far:
package Lab4EventHandling;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Frame3 extends JFrame implements ActionListener {
private Container cPane;
private JLabel tMsg, bMsg;
private JCheckBox americano, espresso, doubleEspresso, latte;
JCheckBox[] boxes = new JCheckBox[]{americano, espresso, doubleEspresso, latte};
private JPanel checkPanel = new JPanel(new GridLayout(0,1));
private Color cl;
private double cost = 0;
private final int WINDOW_WIDTH = 200;
private final int WINDOW_HEIGHT = 200;
private final int x = 550;
private final int y = 400;
public Frame3()
{
cPane = getContentPane();
cl = new Color(150, 150, 250);
cPane.setBackground(cl);
this.setLayout(new BorderLayout(0,1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocation(x,y);
this.add(checkPanel, BorderLayout.CENTER);
tMsg = new JLabel("Choose a coffee:" ,SwingConstants.CENTER);
tMsg.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
this.add(tMsg, BorderLayout.PAGE_START);
americano = new JCheckBox("Americano", false);
checkPanel.add(americano);
americano.addActionListener(this);
espresso = new JCheckBox("Espresso", false);
checkPanel.add(espresso);
espresso.addActionListener(this);
doubleEspresso = new JCheckBox("Double Espresso", false);
checkPanel.add(doubleEspresso);
doubleEspresso.addActionListener(this);
latte = new JCheckBox("Latte", false);
checkPanel.add(latte);
latte.addActionListener(this);
bMsg = new JLabel("Bill is ");
bMsg.setHorizontalAlignment(SwingConstants.CENTER);
bMsg.setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
this.add(bMsg, BorderLayout.SOUTH);
this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
Double[] array = {3.75, 4.00, 4.50, 3.50};
for (JCheckBox box : boxes) {
if(americano.isSelected())
{
cost += 3.75;
String r = String.valueOf(cost);
bMsg.setText(r);
}
if(espresso.isSelected())
{
cost += 4.00;
String r = String.valueOf(cost);
bMsg.setText(r);
}
else if(doubleEspresso.isSelected())
{
cost = 4.50;
String r = String.valueOf(cost);
bMsg.setText(r);
}
else if(latte.isSelected())
{
cost = 3.50;
String r = String.valueOf(cost);
bMsg.setText(r);
}
}
}
public class Frame3Test{
public static void main(String [] args)
{
Frame3 f = new Frame3();
f.setVisible(true);
}
}
Your first problem (which you may or may not have noticed) is your array of JCheckBoxes only contains null elements:
// check boxes are null here
private JCheckBox americano, espresso, doubleEspresso, latte;
// array created with only null elements
JCheckBox[] boxes = new JCheckBox[]{americano, espresso, doubleEspresso, latte};
So you need to create the array after instantiating the actual check boxes.
...
americano = new JCheckBox("Americano", false);
checkPanel.add(americano);
americano.addActionListener(this);
espresso = new JCheckBox("Espresso", false);
checkPanel.add(espresso);
espresso.addActionListener(this);
doubleEspresso = new JCheckBox("Double Espresso", false);
checkPanel.add(doubleEspresso);
doubleEspresso.addActionListener(this);
latte = new JCheckBox("Latte", false);
checkPanel.add(latte);
boxes = new JCheckBox[] {
americano, espresso, doubleEspresso, latte
};
Then the assignment is suggesting to use arrays because you can create another parallel array of prices (which you did). But since you need these prices in parallel you cannot use a for each loop. You need the index. Then you need to recalculate the entire cost every time anything is selected or deselected.
final double[] prices = {
3.75, 4.00, 4.50, 3.50
};
...
double total = 0.0;
for(int i = 0; i < boxes.length; i++) {
if(boxes[i].isSelected()) {
total += prices[i];
}
}
There's two other notes that seem to be outside the scope of the assignment:
You should always make a class for this kind of association.
You should never use double for money. Use BigDecimal or something like it.
Using a class makes logic simpler and not using double makes the calculation not incur error for this decimal addition.
class PricePair {
JCheckBox jCheckBox;
BigDecimal price;
}
BigDecimal total = new BigDecimal("0.00");
for(PricePair option : options) {
if(option.jCheckBox.isSelected()) {
total = total.add(option.price);
}
}
First of all, you're not handling all the checkboxes the same way. For the first two choices, you add the price to the cost:
cost += 3.75;
whereas for the last two choices, you replace the cost:
cost = 4.50;
The first way is the correct way.
Second, there's no reason to have the cost as a field. You should recompute the cost, and it should always start with 0, every time a checkbox selection changes. So cost should be a local variable of the actionPerformed() method.
Third, there's no reason to change the label value before you know the final cost. So the lines
String r = String.valueOf(cost);
bMsg.setText(r);
should only be there once, at the end of the actionPerformed() method, when the final cost is known.
Finally, you want to use it us an array instead of handling each checkbos separately. It's quite easy, you just need to loop over the checkboxes:
double prices = {3.75, 4.00, 4.50, 3.50};
double cost = 0.0;
for (int i = 0; i < boxes.length; i++) {
if (boxes[i].isSelected()) {
double price = prices[i];
cost += price;
}
}
// now display the cost in the label
Although both answers posted here are very helpful I'm adding this one because IMHO arrays are the less Object Oriented thing ever. You can achieve a more robust and OO solution following this hints:
Use
putClientProperty()
method inherited from
JComponent
to hold the prices in the check boxes.
Implement an ActionListener to add/substract the check box price to the total depending on the check box state. Use getClientProperty() method to retrieve the value stored in the check box.
See the example below:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.math.BigDecimal;
import java.math.BigInteger;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Demo {
BigDecimal total = new BigDecimal(BigInteger.ZERO);
private void createAndShowGUI() {
final JLabel totalLabel = new JLabel("Total: ");
ActionListener actionListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JCheckBox checkBox = (JCheckBox)e.getSource();
BigDecimal value = (BigDecimal)checkBox.getClientProperty("price");
total = checkBox.isSelected() ? total.add(value) : total.subtract(value);
StringBuilder sb = new StringBuilder("Total: ").append(total);
totalLabel.setText(sb.toString());
}
};
JCheckBox americano = new JCheckBox("Americano");
americano.addActionListener(actionListener);
americano.putClientProperty("price", new BigDecimal("3.75"));
JCheckBox espresso = new JCheckBox("Espresso");
espresso.addActionListener(actionListener);
espresso.putClientProperty("price", new BigDecimal("4.00"));
JCheckBox doubleEspresso = new JCheckBox("Double Espresso");
doubleEspresso.addActionListener(actionListener);
doubleEspresso.putClientProperty("price", new BigDecimal("4.50"));
JCheckBox latte = new JCheckBox("Latte");
latte.addActionListener(actionListener);
latte.putClientProperty("price", new BigDecimal("3.50"));
JPanel content = new JPanel();
content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
content.add(americano);
content.add(espresso);
content.add(doubleEspresso);
content.add(latte);
content.add(totalLabel);
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(content);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
This way you can forget about mapping every check box with a value using arrays or maps. If you need to add a new sort of coffee you should simply add 4 lines like this:
JCheckBox newCoffee = new JCheckBox("New Coffee");
newCoffee.addActionListener(actionListener);
newCoffee.putClientProperty("price", new BigDecimal("4.00"));
content.add(newCoffee);
I made a program that has a JFrame that contains a JTextField, a button, and two JLabels. When a number is typed into the JTextField, either pressing the enter key or clicking on the JButton should display the number in scientific notation on the second JLabel. When I hit the enter key, it works, however, when I click on the JButton, it does not. It gives me a NumberFormatException: empty string.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyMath extends JPanel implements ActionListener
{
private JTextField textField;
private static JLabel textArea;
private static JLabel comment;
private JButton button;
private static JFrame frame;
public MyMath()
{
comment = new JLabel("Enter a number");
textField = new JTextField();
textField.setSize(new Dimension(10 , 10));
textField.addActionListener(this);
button = new JButton("Go");
button.addActionListener(this);
}
public static void addComponentsToPane(Container pane)
{
textArea = new JLabel(" ");
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.add(new MyMath().textField);
pane.add(new MyMath().button);
pane.add(new MyMath().comment);
pane.add(textArea);
}
public void actionPerformed(ActionEvent evt)
{
String text = textField.getText();
textArea.setText(SciNotation.convertToSciNotation(text));
textArea.setHorizontalAlignment(SwingConstants.CENTER);
comment.setText(text + " in Scientific Notation:");
textField.selectAll();
}
private static void createAndShowGUI()
{
frame = new JFrame("Scientific Notation");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
Container bg = frame.getContentPane();
Dimension d = new Dimension(300, 150);
bg.setPreferredSize(d);
frame.setResizable(false);
frame.getContentPane().setBackground(Color.GREEN);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Point screenCenter = new Point (screen.width/2 , screen.height/2);
Point center = new Point(screenCenter.x - (150), screenCenter.y - (75));
frame.setLocation(center);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
Here is SciNotation.java
import java.awt.Component;
import java.awt.font.TextAttribute;
import java.text.AttributedString;
public class SciNotation
{
public static String convertToSciNotation(String num)
{
num = num.replaceAll("," , "");
if (num.contains("E")) //not working
{
String[] partsE = num.split("E");
String beforeE = partsE[0];
String afterE = partsE[1];
char first = num.charAt(0);
num = first + beforeE;
}
double number = Double.parseDouble(num);
double resultNumber = 0;
int power = 0;
String numString = Double.toString(number);
String[] parts = numString.split("\\.");
String decimals = parts[1];
int decimalInt = Integer.parseInt(decimals);
int numberInt = (int) number;
if(number > -1 && number < 1)
{
String[] low = numString.split("\\.");
String afterLow = low[1];
for(int i = 1; i < 10; i++)
{
String decNums = Integer.toString(i);
afterLow = afterLow.replaceAll(decNums, "");
int zeros = afterLow.length();
power = -1 * (zeros + 1);
resultNumber = number * Math.pow(10, zeros + 1);
decimals = "";
}
}
if(decimalInt == 0)
{
decimals = "";
}
if( number >= 10)
{
power = Integer.toString(numberInt).length() - 1;
resultNumber = numberInt/(Math.pow(10,(power)));
}
if((number >= 1 && number < 10) || (number <= -1 && number > -10))
{
resultNumber = number;
decimals = "";
}
if(number <= -10)
{
power = Integer.toString(numberInt).length() - 2;
resultNumber = numberInt/(Math.pow(10,(power)));
}
return resultNumber + decimals + " x 10^" + power;
}
}
This bug is pretty tricky. You constructed three MyMath instances. So your code was holding a wrong reference to your JTextFiled instance. That's why you couldn't get the right input.
public static void addComponentsToPane(Container pane) {
textArea = new JLabel(" ");
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.add(new MyMath().textField); //MyMath instance 1
pane.add(new MyMath().button); //MyMath instance 2
pane.add(new MyMath().comment); //MyMath instance 3
pane.add(textArea);
}
Here is the right code:
public static void addComponentsToPane(Container pane) {
MyMath myMath = new MyMath();
textArea = new JLabel(" ");
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
pane.add(myMath.textField);
pane.add(myMath.button);
pane.add(myMath.comment);
pane.add(textArea);
}
:)
I'm learning to program in Java and I'm creating my first GUI App. It about creating 100 random numbers. I did it first on cmd like this:
public class RandomNumbers {
public static void main(String[] args){
float n = 100;
float m = 1513;
float a = 19713;
float x = 177963;
float c = 1397;
float r;
float i;
for(i=0;i<=n;i++){
r = (a*x+c)%m;
x = r;
r = r/m;
System.out.println(r);
}
}
}
For some reason when i try to print the 100 random numbers on a text area, it only prints me one.This is the code:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class GUIRandomNumbers extends JFrame implements ActionListener{
public JTextArea area;
public JScrollPane scroll;
public JButton button;
public RandomNumbers(){
setLayout(null);
area = new JTextArea();
area.setEditable(false);
scroll = new JScrollPane(area);
scroll.setBounds(10, 10, 400, 300);
add(scroll);
button = new JButton("Generate");
button.setBounds(10, 650, 100, 25);
add(button);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e){
float n = 100;
float m = 1513;
float a = 19713;
float x = 177963;
float c = 1397;
float r;
float i;
if(e.getSource()==button){
for(i=0;i<=n;i++){
r = (a*x+c)%m;
x = r;
r = r/m;
area.setText(String.valueOf(r));
}
}
}
public static void main(String[] args) {
RandomNumbers p1 = new RandomNumbers();
p1.setBounds(0, 0, 500, 750);
p1.setVisible(true);
}
}
What could be the problem? I will really appreciae your help.
Thanks in advance.
when you do
area.setText(String.valueOf(r));
it overwrites the text on the text area with the new text.
you should use
area.append(String);
method instead.
Use this
area.append(String.valueOf(r) + "\n\r");
instead of
area.setText(String.valueOf(r));
setText(String) method replace the previous text. Use area.append(String) method.
Accordint to docs
Appends the given text to the end of the document. Does nothing if the model is null or the string is null or empty.
At first I suppose that you mean
GUIRandomNumbers p1 = new GUIRandomNumbers();
The reason that makes you see only one number is that one number is written above the other.
I mean that you write 100 times a random number in the textArea!
area.append("text");
is the method that will do your job!
Ok, I'm kinda new to java. I'm making a program that solves for one step equations. I'm having some difficulties running it though. Here is the code for my main file, Main.java:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main extends JFrame implements ActionListener {
private static final long serialVersionUID = 1L;
Solve solve = new Solve();
JButton add = new JButton("Add");
JButton sub = new JButton("Subtract");
JButton mult = new JButton("Multiply");
JButton div = new JButton("Divide");
JButton solv = new JButton("Solve!");
JTextArea one = new JTextArea();
JLabel two = new JLabel(" = ");
JLabel three = new JLabel("X");
JLabel four = new JLabel();
JTextArea five = new JTextArea();
JLabel solved = new JLabel();
JPanel row1 = new JPanel();
JPanel row2 = new JPanel();
JPanel row3 = new JPanel();
public double funct;
public Main() {
super("Solving a one step equation!");
setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
GridLayout layout = new GridLayout();
setLayout(layout);
FlowLayout layout1 = new FlowLayout(FlowLayout.CENTER);
row1.setLayout(layout1);
row1.add(add);
row1.add(sub);
row1.add(mult);
row1.add(div);
row1.add(solv);
add(row1);
add.addActionListener(this);
sub.addActionListener(this);
mult.addActionListener(this);
div.addActionListener(this);
solv.addActionListener(this);
GridLayout layout2 = new GridLayout(1, 1, 1, 1);
row2.setLayout(layout2);
row2.add(one, BorderLayout.CENTER);
row2.add(two, BorderLayout.CENTER);
row2.add(three, BorderLayout.CENTER);
row2.add(four, BorderLayout.CENTER);
row2.add(five);
add(row2, BorderLayout.CENTER);
GridLayout layout3 = new GridLayout(5, 5, 5, 5);
row3.setLayout(layout3);
row3.add(solved);
add(row3);
}
public static void main(String[] args) {
Main frame = new Main();
}
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if(source == add)
{
four.setText(" + ");
funct = 1;
}
else if(source == sub)
{
four.setText(" - ");
funct = 2;
}
else if(source == mult)
{
four.setText(" * ");
funct = 3;
}
else if(source == div)
{
four.setText(" / ");
funct = 4;
}
if(source == solv)
{
if(funct == 1)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Add(Ones, Twos));
}
else if(funct == 2)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Sub(Ones, Twos));
}
else if(funct == 3)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Mult(Ones, Twos));
}
else if(funct == 4)
{
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
solved.setText("X = " + solve.Div(Ones, Twos));
}
}
}
}
Here is the code for my other file, Solve.java
public class Solve {
public double Add(double One, double Two)
{
return One - Two;
}
public double Sub(double One, double Two)
{
return One + Two;
}
public double Mult(double One, double Two)
{
return One / Two;
}
public double Div(double One, double Two)
{
return One * Two;
}
}
Some help would be appreciated. Anyone see what I'm doing wrong?
You get a NumberFormatException once 'Solve' button is clicked. It seems like a copy/paste issue - you are not retrieving the correct numbers. You are trying to convert 'X' string to double. It is best if you give meaningful names to your variables. To fix the exception, try this, replace :
double Ones = Double.parseDouble(three.getText());
double Twos = Double.parseDouble(three.getText());
with:
double Ones = Double.parseDouble(one.getText());
double Twos = Double.parseDouble(five.getText());
Get familiar with Java Code Conventions, Naming Conventions section in particular.
In addition to #Max's helpful answer, here are a few other suggestions:
Setting the frame's layout to new GridLayout() defaults to a single row and column with no padding. As an alternative, consider new GridLayout(0, 1, 5, 5), which produces any number of rows in one column with 5x5 padding. Then you can focus on the layout of each row:
row1.setLayout(new FlowLayout(FlowLayout.CENTER));
row2.setLayout(new FlowLayout(FlowLayout.CENTER));
row3.setLayout(new GridLayout(1, 1, 5, 5));
Move your setVisible() call to the end of the frame's constructor:
pack();
setLocationRelativeTo(null);
setVisible(true);
Consider getRootPane().setDefaultButton(solv) to make the Solve button the default.
Consider making addition the default:
private JLabel four = new JLabel("+");
private int funct = 1; // add by default
Consider using JTextField for number entry:
private JTextField one = new JTextField(10);
private JTextField five = new JTextField(10);
I am writing a Mortgage Calculator for class and I have it working the way I need it to, except everytime I click the "Calculate" button it will just continue to add to the table instead of the table clearing and showing new values. I know my code might look a little sloppy and I have some things commented out that don't need to be there because I'm still working it, but do you have any suggestions?
FYI I am still a beginner learning Java and it has taken me over 20hrs to get this far (and i"m pretty proud of myself!) Thank you!!
//Import all required Packages
import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.text.*;
import java.awt.event.*;
public class MortgageCalculator extends JFrame implements ActionListener {
// Loan Values
double intPrincipal, interestRate, calcPayment, monthlyInterest, currentInterest, principalPaid, newBalance;
int totalMonths;
double[] loanInterest = {5.35, 5.5, 5.75}; // Yearly interest in decimal form
int[] loanTerm = {7, 15, 30}; // Total months of term
String principal;
String comboArray[] = {"7 Years at 5.35%", "15 Years at 5.5%", "30 Years at 5.75%"};
int termYears, termMonths, done, i=0, m=0, p=0;
//Set up panels
JPanel contentPanel;
//Set up labels
JLabel mortgageLabel, paymentLabel, termLabel;
//Set up buttons
JButton calculateButton, clearButton, exitButton;
//TextFields
JTextField txtMortgage = new JTextField(10);
JTextField txtPayment = new JTextField(10);
//New Text Area
JTextArea textarea = new JTextArea();
DecimalFormat df = new DecimalFormat("$###,###.00"); //Formatting the results to decimal form
//Combo Box
JComboBox loansList = new JComboBox();
DefaultTableModel model = new DefaultTableModel();
JTable table = new JTable(model);
//Build GUI
public MortgageCalculator()
{
super();
initializeContent();
}
public void initializeContent()
{
this.setSize(700, 500);
this.setLocation(0, 0);
this.setContentPane(contentPanel());
this.setTitle("Mortgage Calculator");
}
public JPanel contentPanel()
{
contentPanel = new JPanel();
contentPanel.setLayout(null);
//Add labels to the panel
mortgageLabel = new JLabel("Mortgage:");
mortgageLabel.setLocation(200, 30);
mortgageLabel.setSize(100, 25);
contentPanel.add(mortgageLabel);
termLabel = new JLabel("Term & Rate:");
termLabel.setLocation(183, 55);
termLabel.setSize(100, 30);
contentPanel.add(termLabel);
paymentLabel = new JLabel("Monthly Payment:");
paymentLabel.setLocation(158, 85);
paymentLabel.setSize(100, 30);
contentPanel.add(paymentLabel);
//Text Fields
txtMortgage = new JTextField(10);
txtMortgage.setLocation(280, 30);
txtMortgage.setSize(150, 25);
contentPanel.add(txtMortgage);
txtPayment = new JTextField(10);
txtPayment.setLocation(280, 85);
txtPayment.setSize(150, 25);
contentPanel.add(txtPayment);
//Combo Box
loansList.addItem(comboArray[0]);
loansList.addItem(comboArray[1]);
loansList.addItem(comboArray[2]);
loansList.setLocation(280, 55);
loansList.setSize(150, 25);
loansList.addActionListener(this);
contentPanel.add(loansList);
//textarea.setPreferredSize(new Dimension(650, 300));
//JScrollPane scroller = new JScrollPane(textarea);
JScrollPane scroller = new JScrollPane(table);
contentPanel.add(scroller);
scroller.setSize(650,300);
scroller.setLocation(20, 150);
textarea.setLineWrap(true);
model.addColumn("Payment Number");
model.addColumn("Current Interest");
model.addColumn("Principal Paid");
model.addColumn("New Balance");
//Buttons
exitButton = new JButton("Exit");
exitButton.setLocation(450, 30);
exitButton.setSize(100, 25);
contentPanel.add(exitButton);
clearButton = new JButton("Clear");
clearButton.setLocation(450, 55);
clearButton.setSize(100, 25);
contentPanel.add(clearButton);
calculateButton = new JButton("Calculate");
calculateButton.setLocation(450, 85);
calculateButton.setSize(100, 25);
contentPanel.add(calculateButton);
//setup up buttons
calculateButton.addActionListener(this);
clearButton.addActionListener(this);
exitButton.addActionListener(this);
return contentPanel;
}
//Define actions performed for buttons
public void actionPerformed(ActionEvent e)
{
String arg = e.getActionCommand();
if (e.getSource() == loansList) {
switch (loansList.getSelectedIndex()) {
case 0:
i = 0;
break;
case 1:
i = 1;
break;
case 2:
i = 2;
break;
}
}
if (arg == "Calculate")
{
txtPayment.setText("");
principal = txtMortgage.getText();
try {
intPrincipal = Double.parseDouble(principal);
if (intPrincipal <= 0) throw new NumberFormatException();
}
catch(NumberFormatException n){
txtPayment.setText("Please Enter a Postive Numeric Number");
done = 1;
}
if (done == 1)
done = 0;
else {
interestRate = loanInterest[i];
termYears = loanTerm[i];
monthlyInterest = interestRate/(12*100); //calculates monthly interest
termMonths = termYears*12; //calculates term length in months
calcPayment = monthlyInterest*intPrincipal/(1-Math.pow((1+monthlyInterest), -termMonths)); //calculates monthly payment
txtPayment.setText(" " + df.format(calcPayment));
for (m=0; m<=totalMonths; m++) {
totalMonths = loanTerm[i]*12;
currentInterest = intPrincipal * monthlyInterest;
principalPaid = calcPayment - currentInterest;
newBalance = intPrincipal - principalPaid;
intPrincipal = newBalance;
/* printAndAppend(
(m+1) + " " +
df.format(currentInterest) + " " +
df.format(principalPaid) + " " +
df.format(newBalance) + "\n");
//textarea.setText(df.format(currentInterest));
if(intPrincipal <= 1){ break;}*/
// Create a couple of columns
model.addRow(new Object[]{m+1, df.format(currentInterest), df.format(principalPaid), df.format(newBalance)});
if(intPrincipal <= 1){ break;}
}
}
}
else if (e.getSource() == clearButton)
{
txtMortgage.setText(""); //clear Mortgage textfield
txtPayment.setText(""); //clear Payment textfield
txtMortgage.requestFocusInWindow(); //move cursor back to Mortgage textfield
loansList.setSelectedIndex(0);
}
else if (e.getSource() == exitButton)
System.exit(0);
}
public void printAndAppend(String text) {
textarea.append(text);
}
public static void main(String[] args)
{
new MortgageCalculator().setVisible(true);
}
}
To clear all you need to do is set the row count of the model to 0 -- that's it:
else if (e.getSource() == clearButton) {
txtMortgage.setText("");
txtPayment.setText("");
txtMortgage.requestFocusInWindow();
loansList.setSelectedIndex(0);
model.setRowCount(0); //!! added
}
Also, this is not good:
if (arg == "Calculate") {
As you shouldn't use == to compare Strings. If you want to compare Strings, use the equals method:
if (arg.equals("Calculate")) {
or the equalsIgnoreCase method:
if (arg.equalsIgnoreCase("Calculate")) {
The reason this is important is because == checks to see if one String object is the same as another String object, and you really don't care about this. Instead you want to know if one String holds the same chars as another, and that's what equals tests for.
Also, I'd set the model's row count to 0 at the beginning of your calculate method, and this way you can recalculate things without having to clear.