I am trying to code a simple calculator like the one you would see in windows (non-scientific). I can not for the life of me figure out how to properly change the text after pressing an operator but still see the original entry that wont change until the next digit is pressed, have the equals key do the same operation if used multiple times (ie: 5+5 = 10 +5 = 15), and when I input a digit that is the same (5+5) it won't accept the second digit. I know I am very close and am probably missing a certain boolean that could allow my code to work properly, but Im not sure where to look. Thanks for any help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JCalculator extends JFrame implements ActionListener {
/** intialize the jlabel, jbutton, string that makes the buttons and jpanel that will hold the buttons
*
*/
private JTextField display = new JTextField("0", SwingConstants.RIGHT);
private JPanel buttonPanel = new JPanel();
private JPanel displayPanel = new JPanel();
private JButton newButton, divButton, multiButton, equalsButton, clearButton, plusButton, minusButton;
private String[] arrayButtons = {"7","8", "9", "/", "4", "5", "6", "x", "1", "2", "3", "-", "0","C", "=", "+"};
private int operand = 0;
private int firstInput = 0, secondInput = 0, answer = 0;
JCalculator() {
/** creates the jframe */
JFrame jfrm = new JFrame("Calculator");
/** sets the size of the jfrm and then positions it in the center of screen */
jfrm.setSize(480, 300);
jfrm.setLocationRelativeTo(null);
/** sets the program to close on exit */
jfrm.setDefaultCloseOperation(jfrm.EXIT_ON_CLOSE);
/** ImageIcon img = new ImageIcon(JCalculator.png);
*
*/
/**sets initial layout to border */
jfrm.setLayout(new BorderLayout());
/** makes a panel named display that holds the Jtext display
* enables it and justifies it right
*/
displayPanel.setLayout(new BorderLayout());
displayPanel.add(display, BorderLayout.CENTER);
display.setHorizontalAlignment(JTextField.RIGHT);
display.setEnabled(false);
/** makes a panel for buttons that is a grid layout
*
*/
buttonPanel.setLayout(new GridLayout(4,4));
/** makes a loop to make all of the 16 buttons for the calculator
* the operands all have their own specific buttons
*/
for (int i = 0; i < arrayButtons.length; i++) {
if (arrayButtons[i].equals("/")) {
divButton = new JButton(arrayButtons[i]);
divButton.addActionListener(this);
buttonPanel.add(divButton);
} else if (arrayButtons[i].equals("x")) {
multiButton = new JButton(arrayButtons[i]);
multiButton.addActionListener(this);
buttonPanel.add(multiButton);
} else if (arrayButtons[i].equals("=")) {
equalsButton = new JButton(arrayButtons[i]);
equalsButton.addActionListener(this);
buttonPanel.add(equalsButton);
} else if (arrayButtons[i].equals("C")) {
clearButton = new JButton(arrayButtons[i]);
clearButton.addActionListener(this);
buttonPanel.add(clearButton);
} else if (arrayButtons[i].equals("+")) {
plusButton = new JButton(arrayButtons[i]);
plusButton.addActionListener(this);
buttonPanel.add(plusButton);
} else if (arrayButtons[i].equals("-")) {
minusButton = new JButton(arrayButtons[i]);
minusButton.addActionListener(this);
buttonPanel.add(minusButton);
} else {
newButton = new JButton(arrayButtons[i]);
newButton.addActionListener(this);
buttonPanel.add(newButton);
}
}
/** adds the two panels to the jfrm
* sets jfrm visibility to true
* sets equalsButton to the default button
*/
jfrm.add(displayPanel, BorderLayout.NORTH);
jfrm.add(buttonPanel, BorderLayout.CENTER);
jfrm.getRootPane().setDefaultButton(equalsButton);
jfrm.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
String s = ae.getActionCommand();
char stringCheck = s.charAt(0);
if (answer == Integer.parseInt(display.getText())) {
display.setText("0");
}
if (Character.isDigit(stringCheck) && display.getText().length() < 8) {
if (display.getText().equals("0")) {
display.setText(s);
} else {
display.setText(display.getText().concat(s));
}
} if (s.equals("+")){
answer = Integer.parseInt(display.getText());
operand = 1;
} if (s.equals( "-")){
answer = Integer.parseInt(display.getText());
operand = 2;
} if (s.equals("x")){
answer = Integer.parseInt(display.getText());
operand = 3;
} if (s.equals("/")){
answer = Integer.parseInt(display.getText());
operand = 4;
} if (s.equals("C")){
firstInput = 0;
secondInput = 0;
answer = 0;
operand = 0;
display.setText("0");
} if (s.equals("=")){
switch(operand){
case 1:
answer += Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 2:
answer -= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 3:
answer *= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
case 4:
if(Integer.parseInt(display.getText()) > 0 || Integer.parseInt(display.getText()) < 0) {
answer /= Integer.parseInt(display.getText());
display.setText(Integer.toString(answer));
break;
} else {
display.setText("Div by 0");
}
}
if(answer > 100000000 || answer < -100000000){
display.setText("Overlow");
}
}
}
public static void main (String [] args){
/**
* run program
*/
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JCalculator();
}
});
}
}
Related
The question field should contain 36 questions, the answer to these question are on the 36 buttons in the grid.
When the user selects the clicks the correct button answer the button is taken off the grid, the aim is to clear the grid so the grid is empty.
if the user clicks an incorrect button the game restarts.
i am having a problem with adding the question label.
the question field should display 36 question starting with what is 0 + 1 when the user clicks the correct button it then shows
question 2 shows in the field which is what is 1+1 and so till question 36
i have tried to get this by Changing this line of code
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
to this:
gui.statusLabel.setText("what is " + gui.buttonCounter + "+ 1");
but the games doesnt work properly although the correct answer is selected the code keeps saying doing the "else" in this code ie. Incorrect button clicked, start again: what is 0+ 1
if(clickedNumber == gui.buttonCounter){
gui.buttonCounter++;
buttonClicked.setText("");//optional - clears correct selection
if(gui.buttonCounter > gui.ROWS*gui.COLUMNS) gui.reset();
gui.statusLabel.setText("what is 0+ 1" + gui.buttonCounter);
} else {
gui.reset();
gui.statusLabel.setText("Incorrect button clicked, start again: what is 0+ 1");
}
}
}
how do i fix this? so when i click the correct answer button it moves to the next question and does not display Incorrect button clicked, start again: what is 0+ 1.
full code
class NewClass {
final int ROWS = 6;
final int COLUMNS = 6;
JButton[] buttons = new JButton[ROWS * COLUMNS];
JLabel statusLabel = new JLabel("", JLabel.CENTER);
java.util.List<Integer> buttonNumbers = new ArrayList<Integer>();
int buttonCounter = 1;
public NewClass() {
JPanel buttonPanel = new JPanel(new GridLayout(ROWS, COLUMNS));
ButtonListener listener = new ButtonListener(NewClass.this);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x] = new JButton();
buttons[x].addActionListener(listener);
buttonPanel.add(buttons[x]);
buttonNumbers.add(new Integer(x + 1));
}
reset();
JFrame frame = new JFrame();
frame.getContentPane().add(statusLabel, BorderLayout.NORTH);
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void reset() {
Collections.shuffle(buttonNumbers);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x].setText(String.valueOf(buttonNumbers.get(x)));
}
buttonCounter = 1;
statusLabel.setText("Please click button " + buttonCounter);
}
public static void main(String[] args) {
new NewClass();
}
class ButtonListener implements ActionListener {
NewClass gui;
ButtonListener(NewClass g) {
gui = g;
}
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton) e.getSource();
int clickedNumber = Integer.parseInt(buttonClicked.getText());
if (clickedNumber == gui.buttonCounter) {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS)
gui.reset();
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter);
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}
}
}
}
So, taking the code from your previous question and adding
System.out.println("ClickedNumber = " + clickedNumber);
System.out.println("gui.buttonCounter = " + gui.buttonCounter);
Into the actionPerformed method it asks...
"What is 0+1 1" (which should be "What is 0+1"). I click "1", which outputs...
ClickedNumber = 1
gui.buttonCounter = 1
So looking at the if statement;
if (clickedNumber == gui.buttonCounter) {
This is true...
Then it asks...
"What is 2+1". I click "3", which outputs...
ClickedNumber = 3
gui.buttonCounter = 2
So looking at the if statement;
if (clickedNumber == gui.buttonCounter) {
Which is false.
There is a logic error in your code. Basically, it's coming down to you not actually knowing what the question is...
Runnable example
Basically what this does is asks...
"What is " + buttonCounter + "+1"?
In the if condition, we assume the buttonCounter is 0 indexed, meaning we need to increase the comparison by 1
if (clickedNumber == (gui.buttonCounter + 1)) {
Or you could reduce the clickedNumeber by 1
if ((clickedNumber - 1) == gui.buttonCounter) {
Remember, you question is always asks "What's the next number", not what's the current number...
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
class NewClass {
final int ROWS = 6;
final int COLUMNS = 6;
JButton[] buttons = new JButton[ROWS * COLUMNS];
JLabel statusLabel = new JLabel("", JLabel.CENTER);
java.util.List<Integer> buttonNumbers = new ArrayList<Integer>();
int buttonCounter = 1;
public NewClass() {
JPanel buttonPanel = new JPanel(new GridLayout(ROWS, COLUMNS));
ButtonListener listener = new ButtonListener(NewClass.this);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x] = new JButton();
buttons[x].addActionListener(listener);
buttonPanel.add(buttons[x]);
buttonNumbers.add(new Integer(x + 1));
}
reset();
JFrame frame = new JFrame();
frame.getContentPane().add(statusLabel, BorderLayout.NORTH);
frame.getContentPane().add(buttonPanel, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void reset() {
Collections.shuffle(buttonNumbers);
for (int x = 0, y = ROWS * COLUMNS; x < y; x++) {
buttons[x].setText(String.valueOf(buttonNumbers.get(x)));
}
buttonCounter = 0;
statusLabel.setText("Please click button " + buttonCounter + "+1");
}
public static void main(String[] args) {
new NewClass();
}
class ButtonListener implements ActionListener {
NewClass gui;
ButtonListener(NewClass g) {
gui = g;
}
public void actionPerformed(ActionEvent e) {
JButton buttonClicked = (JButton) e.getSource();
int clickedNumber = Integer.parseInt(buttonClicked.getText());
System.out.println("ClickedNumber = " + clickedNumber);
System.out.println("gui.buttonCounter = " + gui.buttonCounter);
if (clickedNumber == (gui.buttonCounter + 1)) {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS) {
gui.reset();
}
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter + "+1");
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}
}
}
}
Updated with winner condition
if (clickedNumber == (gui.buttonCounter + 1)) {
if (gui.buttonCounter == (gui.ROWS * gui.COLUMNS) - 1) {
JOptionPane.showMessageDialog(null, "You Win", "Winner", JOptionPane.INFORMATION_MESSAGE);
} else {
gui.buttonCounter++;
buttonClicked.setText("");// optional - clears correct selection
if (gui.buttonCounter > gui.ROWS * gui.COLUMNS) {
gui.reset();
}
// gui.statusLabel.setText("Please click button" +
// gui.buttonCounter);
gui.statusLabel.setText("what is " + buttonCounter + "+1");
}
} else {
gui.reset();
gui.statusLabel
.setText("Incorrect button clicked, start again: 0 + 1");
}
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.
I need to make the following exceptions: NoSuchRowException if the row is not between 1 and 3, IllegalSticksException if the number of sticks taken is not between 1 and 3, and NotEnoughSticksException if the number of sticks taken is between 1 and 3, but more than the number of sticks remaining in that row. My issue is I really don't understand the syntax. If someone could help me get started with one exception, I think I can figure the others out.
So far I have the main class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nimapp;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
*
* #author jrsullins
*/
public class NimApp extends JFrame implements ActionListener {
private static final int ROWS = 3;
private JTextField[] gameFields; // Where sticks for each row shown
private JTextField rowField; // Where player enters row to select
private JTextField sticksField; // Where player enters sticks to take
private JButton playButton; // Pressed to take sticks
private JButton AIButton; // Pressed to make AI's move
private NimGame nim;
public NimApp() {
// Build the fields for the game play
rowField = new JTextField(5);
sticksField = new JTextField(5);
playButton = new JButton("PLAYER");
AIButton = new JButton("COMPUTER");
playButton.addActionListener(this);
AIButton.addActionListener(this);
AIButton.setEnabled(false);
// Create the layout
JPanel mainPanel = new JPanel(new BorderLayout());
getContentPane().add(mainPanel);
JPanel sticksPanel = new JPanel(new GridLayout(3, 1));
mainPanel.add(sticksPanel, BorderLayout.EAST);
JPanel playPanel = new JPanel(new GridLayout(3, 2));
mainPanel.add(playPanel, BorderLayout.CENTER);
// Add the fields to the play panel
playPanel.add(new JLabel("Row: ", JLabel.RIGHT));
playPanel.add(rowField);
playPanel.add(new JLabel("Sticks: ", JLabel.RIGHT));
playPanel.add(sticksField);
playPanel.add(playButton);
playPanel.add(AIButton);
// Build the array of textfields to display the sticks
gameFields = new JTextField[ROWS];
for (int i = 0; i < ROWS; i++) {
gameFields[i] = new JTextField(10);
gameFields[i].setEditable(false);
sticksPanel.add(gameFields[i]);
}
setSize(350, 150);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
nim = new NimGame(new int[]{3, 5, 7});
draw();
}
// Utility function to redraw game
private void draw() {
for (int row = 0; row < ROWS; row++) {
String sticks = "";
for (int j = 0; j < nim.getRow(row); j++) {
sticks += "| ";
}
gameFields[row].setText(sticks);
}
rowField.setText("");
sticksField.setText("");
}
public void actionPerformed(ActionEvent e) {
// Player move
if (e.getSource() == playButton) {
// Get the row and number of sticks to take
int row = Integer.parseInt(rowField.getText())-1;
int sticks = Integer.parseInt(sticksField.getText());
// Play that move
nim.play(row, sticks);
// Redisplay the board and enable the AI button
draw();
playButton.setEnabled(false);
AIButton.setEnabled(true);
// Determine whether the game is over
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
// Computer move
if (e.getSource() == AIButton) {
// Determine computer move
nim.AIMove();
// Redraw board
draw();
AIButton.setEnabled(false);
playButton.setEnabled(true);
// Is the game over?
if (nim.isOver()) {
JOptionPane.showMessageDialog(null, "You win!");
playButton.setEnabled(false);
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
NimApp a = new NimApp();
}
}
The support class:
package nimapp;
import java.util.Random;
import javax.swing.JOptionPane;
import java.io.*;
import java.lang.*;
public class NimGame {
int x = 1;
int[] Sticks; //creating an array of sticks
int totalSticks = 0;
public NimGame(int[] initialSticks){
Sticks = initialSticks;}
public int getRow(int r){
return Sticks[r];}
public void play(int r, int s) throws IllegalSticksException {
try {
Sticks[r]=Sticks[r]-s;
if(s < 0 || s > 3)
throw new IllegalSticksException();
} catch (IllegalSticksException ex){
JOptionPane.showMessageDialog(null, "Not a valid row!");
} catch (IndexOutOfBoundsException e){
JOptionPane.showMessageDialog(null, "Too Many Sticks!");
}
}
public boolean isOver(){
int theTotal = 0;
for (int i = 0; i< Sticks.length; i++){
theTotal = Sticks[i];
System.out.println(Sticks[i]);
System.out.println(theTotal);
}
totalSticks = theTotal;
if (totalSticks <= 0){
return true;
}
else return false;
}
public void AIMove(){
Random randomInt = new Random ();
boolean tryRemove = true;
while(tryRemove && totalSticks >= 1){
int RandomRow = randomInt.nextInt(3);
if(Sticks[RandomRow] <= 0)//the computer can't remove from this row
continue;
//the max number to remove from row
int size = 3;
if( Sticks[RandomRow] < 3)//this row have least that 3 cards
size = Sticks[RandomRow];//make the max number to remove from the row be the number of cards on the row
int RandomDiscard = randomInt.nextInt(size) + 1;
Sticks[RandomRow] = Sticks[RandomRow] - RandomDiscard;
//I don't know if this is needed, but since we remove a RandomDiscard amount lest decrease the totalSticks
totalSticks = totalSticks - RandomDiscard;
//exit loop
tryRemove = false;
}
if(totalSticks <= 1){
int RandomRow = 0;
Sticks[RandomRow] = Sticks[RandomRow]-1;
isOver();
}
}
}
My issue is I really don't understand the syntax.
There is nothing wrong with the syntax as you have written it.
The problem is that you are catching the exception at the wrong place. You are (apparently) intending play to propagate the IllegalSticksException to its caller. But that won't happen because you are catching it within the play method.
There are two possible fixes depending on what you actually intent to happen.
You could remove the throws IllegalSticksException from the play signature.
You could remove the catch (IllegalSticksException ex){ ... } in play and catch/handle the exception at an outer level.