I made a GUI which basically adds the numbers from the two textfield. The problem is, if I leave the other textfield blank and the other textfield has a number, the result textfield is not updating.
public class AdditionGui extends JFrame implements ActionListener {
private TextField tf1 , tf2 , tf3;
private Label sign, equalsign;
private int sum = 0;
AdditionGui(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
tf1 = new TextField(5);
add(tf1);
tf1.addActionListener(this);
sign = new Label("+");
add(sign);
tf2 = new TextField(5);
add(tf2);
tf2.addActionListener(this);
equalsign = new Label("=");
add(equalsign);
tf3 = new TextField(5);
add(tf3);
setTitle("Sum of two numbers");
setSize(220,120);
setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
int val1 = Integer.parseInt(tf1.getText());
int val2 = Integer.parseInt(tf2.getText());
sum = val1 + val2;
tf3.setText("" + sum);
}
}
A blank text field means its contents cannot be parsed to an Integer. In that case this line of your code will throw NumberFormatException (if tf1 is blank).
int val1 = Integer.parseInt(tf1.getText());
In your actionPerformed() method, check that getText() returns a number.
I suggest setting a blank text field to zero, for example:
String text1 = tf1.getText();
if (text1.length() == 0) {
text1 = "0";
}
int val1 = Integer.parseInt(text1);
String text2 = tf2.getText();
if (text2.length() == 0) {
text2 = "0";
}
int val2 = Integer.parseInt(text2);
int sum = val1 + val2;
tf3.setText(Integer.toString(sum));
Now something for you to think about.
What happens if the user enters a non-digit into one of the text fields?
Related
I am working on a calculator with a GUI. I'm not sure how I should gather all the numbers from the user and do the math for them. I tried storing them in variables, but that doesn't really work since I need to be able to have multiple numbers and operators at one time. Any input would be greatly appreciated. Thanks!
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUI extends JFrame implements ActionListener {
private JFrame frame;
private JPanel buttons;
//
private JPanel text;
private JTextField field;
//
private ImageIcon WCU;
private JLabel labelWCU;
///
JButton[] nums = new JButton[10];
JButton[] functions = new JButton[15];
ArrayList<Double> Addition = new ArrayList<>();
double A;
double S;
double M;
double D;
double Answer;
private JButton num1, num2, num3, num4, num5, num6, num7, num8, num9, num0;
private JButton decimal, add, subtract, multiply, divide, equals, squareRoot;
private JButton sin, cos, tan, exclamation, oneOverX, xSquared, log;
private JButton clear;
double input1 = 0, input2 = 0, answer = 0;
char op;
public GUI() {
frame = new JFrame();
buttons = new JPanel();
//
text = new JPanel();
field = new JTextField(30);
//
WCU = new ImageIcon("WCU.png");
labelWCU = new JLabel(WCU);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Calculator"); // make sure to center
frame.setSize(525,750);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setLayout(new BorderLayout());
frame.add(text, BorderLayout.NORTH);
frame.add(buttons, BorderLayout.CENTER);
text.add(field);
field.setEditable(false);
text.setBackground(Color.RED);
buttons.setBackground(Color.red);
buttons.setBorder(BorderFactory.createEmptyBorder(20,50,300,50));
buttons.setLayout(new GridLayout(6,4,20,20));
//
buttons.add(decimal = new JButton ("."));
functions[0] = decimal;
buttons.add(add = new JButton ("+"));
functions[1] = add;
buttons.add(subtract = new JButton ("-"));
functions[2] = subtract;
buttons.add(multiply = new JButton ("*"));
functions[3] = multiply;
buttons.add(divide = new JButton ("/"));
functions[4] = divide;
buttons.add(equals = new JButton ("="));
functions[5] = equals;
buttons.add(squareRoot = new JButton ("√"));
functions[6] = squareRoot;
buttons.add(num1 = new JButton ("1"));
nums[1] = num1;
buttons.add(num2 = new JButton ("2"));
nums[2] = num2;
buttons.add(num3 = new JButton ("3"));
nums[3] = num3;
buttons.add(num4 = new JButton ("4"));
nums[4] = num4;
buttons.add(num5 = new JButton ("5"));
nums[5] = num5;
buttons.add(num6 = new JButton ("6"));
nums[6] = num6;
buttons.add(num7 = new JButton ("7"));
nums[7] = num7;
buttons.add(num8 = new JButton ("8"));
nums[8] = num8;
buttons.add(num9 = new JButton ("9"));
nums[9] = num9;
buttons.add(num0 = new JButton ("0"));
nums[0] = num0;
buttons.add(sin = new JButton ("sin"));
functions[7] = sin;
buttons.add(cos = new JButton ("cos"));
functions[8] = cos;
buttons.add(tan = new JButton ("tan"));
functions[9] = tan;
buttons.add(exclamation = new JButton ("!"));
functions[10] = exclamation;
buttons.add(oneOverX = new JButton ("1/x"));
functions[11] = oneOverX;
buttons.add(xSquared = new JButton ("x^2"));
functions[12] = xSquared;
buttons.add(log = new JButton ("log"));
functions[13] = log;
text.add(clear = new JButton("Clear"));
functions[14] = clear;
labelWCU.setIcon(WCU);
frame.setVisible(true);
//
for (int i = 0; i < 15; i++){
functions[i].addActionListener(this);
functions[i].setFocusable(false);
}
for (int i = 0; i < 10; i++){
nums[i].addActionListener(this);
nums[i].setFocusable(false);
}
}
public void actionPerformed(ActionEvent e){
for (int i = 0; i < 10; i++){
if(e.getSource() == nums[i]){
field.setText(field.getText().concat(String.valueOf(i)));
}
}
if(e.getSource() == decimal){
field.setText(field.getText().concat("."));
}
if(e.getSource() == add){
A = Double.parseDouble(field.getText());
op = '+';
field.setText("");
}
if(e.getSource() == subtract){
input1 = Double.parseDouble(field.getText());
op = '-';
field.setText("");
}
if(e.getSource() == multiply){
input1 = Double.parseDouble(field.getText());
op = '*';
field.setText("");
}
if(e.getSource() == divide){
input1 = Double.parseDouble(field.getText());
op = '/';
field.setText("");
}
if(e.getSource() == equals){
field.setText(String.valueOf(Addition));
}
if(e.getSource() == clear){
field.setText("");
A = 0;
}
}
}
I don't fully understand the purpose of all fields in your class, so I'll propose my own set. If we (ab)use the text field as storage for the current value, two state fields are enough for the basic functionality. It's not necessary to store any more data:
private String firstBinaryOperand = null;
private char binaryOp = ' ';
These fields are used if there is a pending binary operation such as + or -. We don't need them for unary operations. For example, if the user types "700 + 200 =", then
When the "+" button is pressed for the first time, the currently displayed value (700) is stored in firstBinaryOperand and '+' in binaryOp.
When the "=" button is pressed, the current value (200) and the value cached in firstBinaryOperand are added and the result (900) written into the text field.
We therefore need a method that evaluates a pending binary operation if there is one and writes the result into the text field:
// Evaluate pending binary operation, if there is one.
private void evaluateBinaryOp() {
if (binaryOp != ' ') {
double firstOperand = Double.parseDouble(firstBinaryOperand);
double secondOperand = Double.parseDouble(field.getText());
double result;
if (binaryOp == '+') {
field.setText(Double.toString(firstOperand + secondOperand));
} else if (binaryOp == '-') {
field.setText(Double.toString(firstOperand - secondOperand));
}
// Implementation of further binary operands ...
// Update state, there is no longer a pending binary operation
firstBinaryOperand = null;
binaryOp = ' ';
}
}
Addition as an example of a binary operation:
if (e.getSource() == add){
evaluateBinaryOp(); // evaluate pending binary op, if any
firstBinaryOperand = field.getText();
binaryOp = '+';
field.setText("0");
}
Unary operations are simpler, but we still have to check whether there is a pending binary operation and evaluate it first if this is the case:
if (e.getSource() == oneOverX) {
evaluateBinaryOp(); // evaluate pending binary op, if any
double currentValue = Double.parseDouble(field.getText());
field.setText(Double.toString(1.0 / currentValue));
}
All other unary and binary operations can be implemented using the same pattern.
This is going to give you a very basic calculator whose behavior differs a bit from the usual. For example, if the user presses +, they will not see the intermediate result but always 0. The intermediate result isn't lost though as it is stored in the firrstBinaryOperand field in the background. The correct result will be shown once = or another unary operator is used. I hope this answers your question and is enough to get you started, you can then refine the behavior in a second step.
I have been trying to create a (ugly) calculator and I am having problems with "=" sign. I know how to convert numbers (in string) to numbers (in int), but the problem here is mainly */-+. I have absolutely no idea what to do when they are added to the situation.
Here is a gif of the calculator: http://gyazo.com/98781eaaca0b3152967e6370cad3df15
package megetenkelkalkis;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.*;
import java.text.DecimalFormat;
import javax.swing.*;
class Kalkulator extends JFrame{
private String textfield = "";
private String replace ="";
private JButton btn0 = new JButton("0");
private JButton btn1 = new JButton("1");
private JButton btn2 = new JButton("2");
private JButton btn3 = new JButton("3");
private JButton btn4 = new JButton("4");
private JButton btn5 = new JButton("5");
private JButton btn6 = new JButton("6");
private JButton btn7 = new JButton("7");
private JButton btn8 = new JButton("8");
private JButton btn9 = new JButton("9");
private JButton btnlik = new JButton("=");
private JButton btngange = new JButton("*");
private JButton btndele = new JButton("/");
private JButton btnpluss = new JButton("+");
private JButton btnminus = new JButton("-");
private JTextField tekst = new JTextField();
private JButton btndel= new JButton("DEL");
JPanel p = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
public Kalkulator(String tittel){
tekst.setPreferredSize(new Dimension(310,25));
setTitle(tittel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.add(btn0);
p.add(btn1);
p.add(btn2);
p.add(btn3);
p.add(btn4);
p.add(btn5);
p.add(btnlik);
p2.add(btn6);
p2.add(btn7);
p2.add(btn8);
p2.add(btn9);
p2.add(btndele);
p2.add(btngange);
p2.add(btnpluss);
p2.add(btnminus);
p3.add(tekst);
p3.add(btndel);
add(p, BorderLayout.SOUTH);
add(p2, BorderLayout.CENTER);
add(p3, BorderLayout.NORTH);
pack();
Knappelytter knappelytteren = new Knappelytter();
btn0.addActionListener(knappelytteren);
btn1.addActionListener(knappelytteren);
btn2.addActionListener(knappelytteren);
btn3.addActionListener(knappelytteren);
btn4.addActionListener(knappelytteren);
btn5.addActionListener(knappelytteren);
btn6.addActionListener(knappelytteren);
btn7.addActionListener(knappelytteren);
btn8.addActionListener(knappelytteren);
btn9.addActionListener(knappelytteren);
btnlik.addActionListener(knappelytteren);
btndele.addActionListener(knappelytteren);
btngange.addActionListener(knappelytteren);
btnminus.addActionListener(knappelytteren);
btnpluss.addActionListener(knappelytteren);
btndel.addActionListener(knappelytteren);
}
class Knappelytter implements ActionListener{
public void actionPerformed (ActionEvent hendelse){
JButton valgtKnapp = (JButton) hendelse.getSource();
String knapp = valgtKnapp.getText();
if (knapp.equals("0")){
textfield += "0";
tekst.setText(textfield);
}else if(knapp.equals("1")){
textfield += "1";
tekst.setText(textfield);
}else if(knapp.equals("2")){
textfield += "2";
tekst.setText(textfield);
}else if(knapp.equals("3")){
textfield += "3";
tekst.setText(textfield);
}else if(knapp.equals("4")){
textfield += "4";
tekst.setText(textfield);
}else if(knapp.equals("5")){
textfield += "5";
tekst.setText(textfield);
}else if(knapp.equals("6")){
textfield += "6";
tekst.setText(textfield);
}else if(knapp.equals("7")){
textfield += "7";
tekst.setText(textfield);
}else if(knapp.equals("8")){
textfield += "8";
tekst.setText(textfield);
}else if(knapp.equals("9")){
textfield += "9";
tekst.setText(textfield);
}else if(knapp.equals("*")){
textfield += "*";
tekst.setText(textfield);
}else if(knapp.equals("/")){
textfield += "/";
tekst.setText(textfield);
}else if(knapp.equals("-")){
textfield += "-";
tekst.setText(textfield);
}else if(knapp.equals("+")){
textfield += "+";
tekst.setText(textfield);
}else if(knapp.equals("DEL")){
tekst.setText(" ");
textfield = " ";
}else if(knapp.equals("=")){
else if(knapp.equals("=")){
/EDIT RIGHT HERE
String[] parts = textfield.split("-*/+");
for (int i = 0; i < textfield.length(); i++){
if (textfield.charAt(i) == ('-')){
String one = parts[0];
String two = parts[1];
int one1 = Integer.parseInt(one);
int one2 = Integer.parseInt(two);
int one3 = one1-one2;
String one4 = String.valueOf(one3);
tekst.setText(one4);
}
}
}
}
public class MegetEnkelKalkis {
public static void main(String[] args) {
Kalkulator Skole = new Kalkulator("Kalkulator");
Skole.setVisible(true);
}
}
Get the Input
Seperate it from the Operands ( *, /, -, + )
Cast the strings to int's ( Integer.valueOf() throws a NumberFormatException)
Do a if else for the operands and then multiply, divide, add or substract the ints
What you need is a string calculator. You basically parse the contents of textfield following the regular maths rules. It is a bit of work but not too hard.
Basically just follow this:
Recursion might be quite suitable for that, so build a function that takes a string and returns the result as an int.
Search for all occurrences of a parameter (e.g. ) starting with the highest priority ones ( and /)
If you encounter that parameter split the string there into two halves (left of the parameter and right of the parameter)
Recursively follow the same rules with the left and right part of the string.
If the String only contains one number, parse that number using Integer.parseInt() and return it.
Calculate the result of left operator right, so e.g. left * right, if the operator is *
Return the result of the calculation.
Or you calculate via nashorn (javascript) engine ;)
private ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("nashorn");
double result = (double) scriptEngine.eval(formula)
You should build a reverse polish notation, which is the easiest way to parse and evaluate methmatical formulas. there are plenty of examples how to do that in Java on the web.
There are anumber of ways to do this, but recommendation is that you create two doubles. When the user clicks +,-,\ or * parse the number before it into a double. Thenwhen they press = parse everything between + and = into a double, then perform the calculation using those two doubles and output the result. You can set a flag to determine which operation to perform. for example the + button could set a boolean called Plus = true; Then when you perform the operation check which bools are true. IF more or less than one, tell the user the input was invalid, otherwise perform the operation
There is definitely lot of scope of improvement in the code, as suggested by others, but if you want to keep it as it is and working, then here is the code:
.
.
.
}else if(knapp.equals("=")){
String nytekst = textfield;
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
try {
Double result = (Double) engine.eval(nytekst);
System.out.println(result);
tekst.setText(result.toString());
} catch (ScriptException e) {
e.printStackTrace();
}
}
.
.
.
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);
}
:)
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.