Making a calculator about letter grades - java

I am taking Maths and I want to make a calculator which tells me the each note I need to take in the final exam to get each letter grade. In the syllabus it tells us that our note is calculated by this:
MT1 - First midterm %26.6
MT2- Second midterm %26.6
F- Final % 26.6
Q - Quizzes % 10
HW- Homeworks % 10
These are the grade intervals:
A 80-100
A- 75-80
B+ 70-75
B 65-70
B- 60-65
C+ 55-60
C 50-55
C- 45-50
D+ 40-45
D+ 30-40
F 0-30
You enter MT1, MT2, Q, HW in the JTextFields and when you click the button it will update the jlabel's near the letter grades. When I run the code for the first time, it works but when I want to change it program doesn't update the numbers. Could you help?
Final_Calculator:
import javax.swing.*;
import java.awt.*;
public class Final_Calculator extends JFrame
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Final Calculator");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Results());
frame.pack();
frame.setVisible(true);
}
}
Grades:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Grades extends JPanel
{
private JLabel l1, l2, l3, l4;
private JTextField t1, t2, t3, t4;
private double sum,result, MT1, MT2, Q, HW;
private JButton button;
public Grades()
{
setPreferredSize(new Dimension(200,100));
l1 = new JLabel("MT1");
l2 = new JLabel("MT2");
l3 = new JLabel("Q");
l4 = new JLabel("HW");
t1 = new JTextField("100");
t2 = new JTextField("100");
t3 = new JTextField("100");
t4 = new JTextField("100");
button = new JButton("Click!");
TextListener listener = new TextListener();
button.addActionListener(listener);
add(l1);
add(l2);
add(l3);
add(l4);
add(t1);
add(t2);
add(t3);
add(t4);
add(button);
}
public double getMT1()
{
return Double.parseDouble(t1.getText());
}
public double getMT2()
{
return Double.parseDouble(t2.getText());
}
public double getQ()
{
return Double.parseDouble(t3.getText());
}
public double getHW()
{
return Double.parseDouble(t4.getText());
}
public void sum()
{
MT1 = getMT1();
MT2 = getMT2();
Q = getQ();
HW = getHW();
sum = (MT1 * 26.6) + (MT2 * 26.6) + (Q * 10) + (HW * 10);
}
public double getA()
{
sum();
result = (8000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getAminus()
{
sum();
result = (7500 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getBplus()
{
sum();
result = (7000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getB()
{
sum();
result = (6500 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getBminus()
{
sum();
result = (6000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getCplus()
{
sum();
result = (5500 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getC()
{
sum();
result = (5000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getCminus()
{
sum();
result = (4500 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getDplus()
{
sum();
result = (4000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
public double getD()
{
sum();
result = (3000 - sum) / 26.6;
if (result <= 0)
{
return 0;
}
return result;
}
private class TextListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if(source == button)
{
MT1 = Double.parseDouble(t1.getText());
MT2 = Double.parseDouble(t2.getText());
Q = Double.parseDouble(t3.getText());
HW = Double.parseDouble(t4.getText());
sum();
getA();
getAminus();
getBplus();
getB();
getBminus();
getCplus();
getC();
getCminus();
getDplus();
getD();
}
}
}
}
Results:
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Results extends JPanel
{
private JLabel f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f11,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11;
private JPanel panel1, panel2;
private Grades grades;
public Results()
{
grades = new Grades();
setPreferredSize(new Dimension(800,800));
setLayout(new BorderLayout());
panel1 = new JPanel();
panel1.setLayout(new GridLayout(11,2));
panel1.setPreferredSize(new Dimension(200,200));
panel2 = new JPanel();
panel2.setPreferredSize(new Dimension(400,400));
f1 = new JLabel("Final");
g1 = new JLabel("Grade");
f2 = new JLabel(Double.toString(grades.getA()));
g2 = new JLabel(" A");
f3 = new JLabel(Double.toString(grades.getAminus()));
g3 = new JLabel(" A-");
f4 = new JLabel(Double.toString(grades.getBplus()));
g4 = new JLabel(" B+");
f5 = new JLabel(Double.toString(grades.getB()));
g5 = new JLabel(" B");
f6 = new JLabel(Double.toString(grades.getBminus()));
g6 = new JLabel(" B-");
f7 = new JLabel(Double.toString(grades.getCplus()));
g7 = new JLabel(" C+");
f8 = new JLabel(Double.toString(grades.getC()));
g8 = new JLabel(" C");
f9 = new JLabel(Double.toString(grades.getCminus()));
g9 = new JLabel(" C-");
f10 = new JLabel(Double.toString(grades.getDplus()));
g10 = new JLabel(" D+");
f11 = new JLabel(Double.toString(grades.getD()));
g11 = new JLabel(" D");
panel1.add(f1);
panel1.add(g1);
panel1.add(f2);
panel1.add(g2);
panel1.add(f3);
panel1.add(g3);
panel1.add(f4);
panel1.add(g4);
panel1.add(f5);
panel1.add(g5);
panel1.add(f6);
panel1.add(g6);
panel1.add(f7);
panel1.add(g7);
panel1.add(f8);
panel1.add(g8);
panel1.add(f9);
panel1.add(g9);
panel1.add(f10);
panel1.add(g10);
panel1.add(f11);
panel1.add(g11);
panel2.add(grades);
add(panel2, BorderLayout.NORTH);
add(panel1, BorderLayout.CENTER);
}
}

From the looks of it/only working once, it looks like you are not updating the label after clicking the button.Label text have to updated via label.setText(""); just calling the method wont do anything.

Related

Converting a program to use arrays INSTEAD of ArrayLists

I have a class ShoppingCart that utilizes ArrayList methods to carry out the program which is basically a program where you add groceries to your cart and such. However, I want to use arrays to do the program instead of ArrayLists since I want to work on my array knowledge. Here is the ShoppingCart class
import java.util.*;
#SuppressWarnings("serial")
public class ShoppingCart extends ArrayList<Selections> {
// FIELDS
private boolean discount;
// Selections[]......
// CONSTRUCTOR
public ShoppingCart() {
super();
discount = false;
}
// Adding to the Collection
public boolean add(Selections next) {
// check to see if it's already here
for (int i = 0; i < this.size(); i++)
if (get(i).equals(next)) {
set(i, next); // replace it
return true;
}
super.add(next); // add new to the array
return false;
}
// The GUI only know if check is on or off
public void setDiscount(boolean disc) {
discount = disc; // match discount from GUI
}
// total of selections
public double getTotal() {
double sum = 0.0;
for (int i = 0; i < this.size(); i++)
sum += get(i).priceFor();
if (discount) sum *= 0.9;
return sum;
}
}
The Selections class that is being used for the individual groceries.
import java.text.*;
// W.P. Iverson, instructor
// January 2018 for CS211
// Class that combines Item and ItemOrder
public class Selections {
// FIELDS
private String name; // friendly name
private double price; // cost of one
private int bulkQuantity; // when bulk price kicks in
private double bulkPrice; // price for the bulk quantity
private int quantity; // how many we are buying
private boolean hasBulk; // internally used
private NumberFormat curr; // for nice $12.34 currency formatting
// CONSTRUCTORS
public Selections(String name, double price) {
this(name, price, -99999, 99999.); // flag that nothing is selected with 99999
}
public Selections(String thing, double amount, int qty, double bulk) {
name = thing;
price = amount;
if (qty > 0) hasBulk = true;
bulkQuantity = qty;
bulkPrice = bulk;
quantity = 0; // starts with zero selected by user, GUI changes it later
curr = NumberFormat.getCurrencyInstance();
}
// decides how many we're buying
public void setQuantity(int number) {
quantity = number;
}
// calculates the price for this quantity
public double priceFor() {
if (hasBulk && quantity >= bulkQuantity)
return quantity / bulkQuantity * bulkPrice + quantity % bulkQuantity * price;
else
return quantity * price;
}
// basic output for console or GUI text
public String toString() {
if (hasBulk)
return name + ", " + curr.format(price) + " (" + bulkQuantity + " for " + curr.format(bulkPrice) + ")";
else
return name + ", " + curr.format(price);
}
}
I made a JFrame for the program already but just want to get it to use regular arrays instead! Thanks for your help.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.*;
#SuppressWarnings("serial")
public class ShoppingFrame extends JFrame {
private ShoppingCart items;
private JTextField total;
public ShoppingFrame(Selections[] array) {
// create frame and order list
setTitle("CS211 Shopping List");
setDefaultCloseOperation(EXIT_ON_CLOSE);
items = new ShoppingCart();
// set up text field with order total
total = new JTextField("$0.00", 12);
total.setEditable(false);
total.setEnabled(false);
total.setDisabledTextColor(Color.BLACK);
JPanel p = new JPanel();
p.setBackground(Color.blue);
JLabel l = new JLabel("order total");
l.setForeground(Color.YELLOW);
p.add(l);
p.add(total);
add(p, BorderLayout.NORTH);
p = new JPanel(new GridLayout(array.length, 1));
for (int i = 0; i < array.length; i++)
addItem(array[i], p);
add(p, BorderLayout.CENTER);
p = new JPanel();
add(makeCheckBoxPanel(), BorderLayout.SOUTH);
// adjust size to just fit
pack();
}
// Sets up the "discount" checkbox for the frame
private JPanel makeCheckBoxPanel() {
JPanel p = new JPanel();
p.setBackground(Color.blue);
final JCheckBox cb = new JCheckBox("qualify for discount");
p.add(cb);
cb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
items.setDiscount(cb.isSelected());
updateTotal();
}
});
return p;
}
// adds a product to the panel, including a textfield for user input of
// the quantity
private void addItem(final Selections product, JPanel p) {
JPanel sub = new JPanel(new FlowLayout(FlowLayout.LEFT));
sub.setBackground(new Color(0, 180, 0));
final JTextField quantity = new JTextField(3);
quantity.setHorizontalAlignment(SwingConstants.CENTER);
quantity.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateItem(product, quantity);
quantity.transferFocus();
}
});
quantity.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
updateItem(product, quantity);
}
});
sub.add(quantity);
JLabel l = new JLabel("" + product);
l.setForeground(Color.white);
sub.add(l);
p.add(sub);
}
// When the user types a new value into one of the quantity fields,
// parse the input and update the ShoppingCart. Display an error
// message if text is not a number or is negative.
private void updateItem(Selections product, JTextField quantity) {
int number;
String text = quantity.getText().trim();
try {
number = Integer.parseInt(text);
} catch (NumberFormatException error) {
number = 0;
}
if (number <= 0 && text.length() > 0) {
Toolkit.getDefaultToolkit().beep();
quantity.setText("");
number = 0;
}
product.setQuantity(number);
items.add(product);
updateTotal();
}
// reset the text field for order total
private void updateTotal() {
double amount = items.getTotal();
total.setText(NumberFormat.getCurrencyInstance().format(amount));
}
public static void main(String[] args) {
Selections[] array = new Selections[10];
array[0] = new Selections("silly putty", 3.95, 10, 19.99);
array[1] = new Selections("silly string", 3.50, 10, 14.95);
array[2] = new Selections("bottle o bubbles", 0.99);
array[3] = new Selections("Nintendo Wii system", 389.99);
array[4] = new Selections("Mario Computer Science Party 2 (Wii)", 49.99);
array[5] = new Selections("Don Knuth Code Jam Challenge (Wii)", 49.99);
array[6] = new Selections("Computer Science pen", 3.40);
array[7] = new Selections("Rubik's cube", 9.10);
array[8] = new Selections("Computer Science Barbie", 19.99);
array[9] = new Selections("'Java Rules!' button", 0.99, 10, 5.0);
ShoppingFrame f = new ShoppingFrame(array);
f.setVisible(true);
}
}
You can use an array member variable in ShoppingCart class like this:
private Selections[] selectionsArray;
instead of extending ArrayList<Selections>. (Then you will have to handle resizing the array yourself.)

JOptionPane.showMessageDialog keeps reappearing

My code is supposed to ensure that users only enter a binary string. Everything goes right and in order if I enter a correct binary number (1, 0). But when I enter a wrong number (alphabet or number other than 0 and 1) JOptionPane.ShowMessageDialog appears showing the error message, and when I click "OK" or "Cross" Button it reappears again. So to close the app I have to use the process manager to kill "java.exe".
Here is the complete code for my app:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class Bn extends JFrame {
private JLabel l1;
private JLabel l2;
private JLabel l3;
private JTextField tf;
private JButton oc;
private JButton hd;
private JButton dc;
public Bn() {
setTitle("Binary Conversion");
setSize(350 , 190);
setResizable(false);
setLocation(720 , 200);
//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.CENTER, 25, 10));
l1 = new JLabel(">>>>>>>>BINARY CONVERSION<<<<<<<<");
l2 = new JLabel("Enter The Number:");
l3 = new JLabel(" Convert to: ");
tf = new JTextField(25);
oc = new JButton("Octal");
hd = new JButton("Hexa Decimal");
dc = new JButton("Decimal");
add(l1); // Binary conversion
add(l2); // Enter The Number
add(tf); // Text Field
add(l3); // Conver to
add(oc); // Octal
add(hd); // Hexa Decimal
add(dc); // Decimal
oc.addActionListener(new cvr());
hd.addActionListener(new cvr());
dc.addActionListener(new cvr());
setVisible(true);
}
void res()
{
int b = 0;
String num = tf.getText();
int i , l;
l = num.length();
char ch;
do
{
for (i=0 ; i<l ; i++)
{
b = 0;
ch = num.charAt(i);
if (Character.isDigit(ch) && (ch == 48 || ch == 49))
b=1;
else
{
JOptionPane.showMessageDialog(null, "Please enter a binary number (1 , 0)");
}
}
}
while(b != 1);
}
void occ()
{
res();
String num = tf.getText();
long dec = Long.parseLong(num,2);
String oct = Long.toOctalString(dec);
JOptionPane.showMessageDialog(null, "Octal equivalent is: "+ oct);
}
void hdc()
{
res();
String num = tf.getText();
long dec = Integer.parseInt(num,2);
String hex = Long.toHexString(dec);
JOptionPane.showMessageDialog(null, "Hexa Decimal equivalent is: "+ hex);
}
void dcc()
{
res();
String num = tf.getText();
long decimal = 0, temp, i = 0;
temp = Long.parseLong(num);
while (temp != 0) {
long r = temp % 10;
long value = r * (int)Math.pow(2, i);
i++;
decimal = decimal + value;
temp /= 10;
}
JOptionPane.showMessageDialog(null, "Decimal equivalent is: "+ decimal);
}
private class cvr implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == oc)
{
occ();
}
if (e.getSource() == hd)
{
hdc();
}
if (e.getSource() == dc)
{
dcc();
}
}
}
public static void main(String args[])
{
Bn obj = new Bn();
}
}
The code for JOptionPane is located in void res() method. How can I close this Dialog pane so I may reenter the value for input?
Remove the do { } while loop
do
{
for (i=0 ; i < l ; i++)
{
b = 0;
ch = num.charAt(i);
if (Character.isDigit(ch) && (ch == 48 || ch == 49))
b=1;
else
{
JOptionPane.showMessageDialog(null, "Please enter a binary number (1 , 0)");
}
}
}
while(b != 1);

NumberFormatException: empty string when clicking the JButton?

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);
}
:)

Recursively find connectivity in a 2D Array

I have a game and I'm having trouble implementing the scores.
Prof stated that it must be recursively done without a for-loop. But I'm having trouble thinking of the algorithm that is used. This is the game.
The score system works so it starts with the valve pipe (Pipe.ValvePipe) and then it checks to see how many pipes are connected to it. Is there a certain algorithm/strategy for doing this type of recursion? Thank you in advance.
pipe.java
public class Pipe {
private boolean openAtTop;
private boolean openAtRight;
private boolean openAtBottom;
private boolean openAtLeft;
private boolean isValve;
private static Pipe VALVE_PIPE;
public Pipe(boolean t, boolean r, boolean b, boolean l, boolean valve) {
openAtTop = t; openAtBottom = b; openAtRight = r; openAtLeft = l;
isValve = valve;
}
public boolean isValve() { return isValve; }
public static Pipe ValvePipe() { return new Pipe(false, false, true, false, true); }
public boolean isValid() { return !(!openAtTop&&!openAtBottom&&!openAtLeft&&!openAtRight); }
public static Pipe RandomPipe() {
Pipe p;
do {
p = new Pipe(Math.random() < 0.5, Math.random() < 0.5,
Math.random() < 0.5, Math.random() < 0.5, false);
} while (!p.isValid());
return p;
}
public boolean isOpenAtTop() { return openAtTop; }
public boolean isOpenAtBottom() { return openAtBottom; }
public boolean isOpenAtLeft() { return openAtLeft; }
public boolean isOpenAtRight() { return openAtRight; }
public boolean fitsBelow(Pipe p) {
return (p == null) || (!openAtTop && !p.isOpenAtBottom()) || (openAtTop && p.isOpenAtBottom());
}
public boolean fitsAbove(Pipe p) {
return (p == null) || (!openAtBottom && !p.isOpenAtTop()) || (openAtBottom && p.isOpenAtTop());
}
public boolean fitsToLeftOf(Pipe p) {
return (p == null) || (!openAtRight && !p.isOpenAtLeft()) || (openAtRight && p.isOpenAtLeft());
}
public boolean fitsToRightOf(Pipe p) {
return (p == null) || (!openAtLeft && !p.isOpenAtRight()) || (openAtLeft && p.isOpenAtRight());
}
public String toString() {
String s = "";
if (openAtTop) s+="1"; else s+="0";
if (openAtRight) s+="1"; else s+="0";
if (openAtBottom) s+="1"; else s+="0";
if (openAtLeft) s+="1"; else s+="0";
return s;
}
public int toInt() {
int s = 0;
if (openAtTop) s+=8;
if (openAtRight) s+=4;
if (openAtBottom) s+=2;
if (openAtLeft) s+=1;
return s;
}
}
PipeGameView.java
import java.awt.*;
import javax.swing.*;
// Subclass JFrame so you can display a window
public class PipeGameView extends JPanel {
private PipeGame game; // The model
private BoardPanel tiles;
private JButton[][] buttons;
private JProgressBar timeBar;
private JButton startStop;
private JRadioButton twoMinButton, tenMinButton, noLimitButton;
private JLabel statusLabel;
// This constructor builds the window
public PipeGameView(PipeGame g) {
game = g; // Store the model for access in update()
// Set up the components
tiles = new BoardPanel();
tiles.setLayout(new GridLayout(game.getRows(), game.getRows()));
buttons = new JButton[game.getRows()][game.getRows()];
// Add the buttons to the tile panel
ImageIcon ic = new ImageIcon("Pipes0000.GIF");
for (int r=0; r<game.getRows(); r++) {
for (int c=0; c<game.getRows(); c++) {
buttons[r][c] = new JButton(ic);
tiles.add(buttons[r][c]);
}
}
// Now layout the components using a gridbag layout
GridBagLayout layout = new GridBagLayout();
GridBagConstraints layoutConstraints = new GridBagConstraints();
this.setLayout(layout);
// Add the Start/Stop Button
startStop = new JButton("Start Game");
layoutConstraints.gridx = 0; layoutConstraints.gridy = 0;
layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(startStop, layoutConstraints);
this.add(startStop);
// Add the JRadioButtons
twoMinButton = new JRadioButton("2 minutes");
tenMinButton = new JRadioButton("10 minutes");
noLimitButton = new JRadioButton("No Time Limit");
ButtonGroup group = new ButtonGroup();
group.add(twoMinButton); group.add(tenMinButton); group.add(noLimitButton);
layoutConstraints.gridx = 1;
layout.setConstraints(twoMinButton, layoutConstraints);
this.add(twoMinButton);
layoutConstraints.gridx = 2;
layout.setConstraints(tenMinButton, layoutConstraints);
this.add(tenMinButton);
layoutConstraints.gridx = 3;
layout.setConstraints(noLimitButton, layoutConstraints);
this.add(noLimitButton);
// Add the tiles
layoutConstraints.gridx = 0; layoutConstraints.gridy = 1;
layoutConstraints.gridwidth = 4; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.BOTH;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.NORTHWEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(tiles, layoutConstraints);
this.add(tiles);
// Add the label
statusLabel = new JLabel("Time Left: ");
statusLabel.setVisible(false);
layoutConstraints.gridx = 0; layoutConstraints.gridy = 2;
layoutConstraints.gridwidth = 1; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.NONE;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.WEST;
layoutConstraints.weightx = 0.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(statusLabel, layoutConstraints);
this.add(statusLabel);
timeBar = new JProgressBar(0, 100);
timeBar.setValue(100);
timeBar.setVisible(false);
layoutConstraints.gridx = 1; layoutConstraints.gridy = 2;
layoutConstraints.gridwidth = 3; layoutConstraints.gridheight = 1;
layoutConstraints.fill = GridBagConstraints.HORIZONTAL;
layoutConstraints.insets = new Insets(2, 2, 2, 2);
layoutConstraints.anchor = GridBagConstraints.EAST;
layoutConstraints.weightx = 5.0; layoutConstraints.weighty = 0.0;
layout.setConstraints(timeBar, layoutConstraints);
this.add(timeBar);
update();
}
// Get methods for the components
public JButton getButton(int r, int c) { return buttons[r][c]; }
public JButton getStartStopButton() { return startStop; }
public JProgressBar getTimeBar() { return timeBar; }
public JRadioButton getTwoMinButton() { return twoMinButton; }
public JRadioButton getTenMinButton() { return tenMinButton; }
public JRadioButton getNoLimitButton() { return noLimitButton; }
public void setGame(PipeGame g) { game = g; }
// This is called whenever the model has changed. Note that this code is not efficient. All ICONS should really
// be loaded upon game start and stored into a static array of ImageIcons. Then, these static icons should be
// used instead of re-creating icons each time.
public void update() {
// Update the look of the buttons
for (int r=0; r<game.getRows(); r++) {
for (int c=0; c<game.getRows(); c++) {
if (game.isOver())
buttons[r][c].setEnabled(false);
else
buttons[r][c].setEnabled(true);
if (game.getPipe(r,c) == null)
buttons[r][c].setSelected(false);
else {
// Determine the portion of the icon's filename that matches the pipe
String currentPipeCodes = "Start";
if (!game.getPipe(r,c).isValve())
currentPipeCodes = game.getPipe(r,c).toString();
buttons[r][c].setSelectedIcon(new ImageIcon("pipes"+ currentPipeCodes +".GIF"));
buttons[r][c].setSelected(true);
}
}
}
// Update the start/stop button
if (game.isOver())
startStop.setText("Start");
else
startStop.setText("Stop");
// Update the radio buttons
if (game.isOver()) {
twoMinButton.setEnabled(true);
tenMinButton.setEnabled(true);
noLimitButton.setEnabled(true);
}
else {
twoMinButton.setEnabled(false);
tenMinButton.setEnabled(false);
noLimitButton.setEnabled(false);
}
// Update the status label
if (game.isOver()) {
statusLabel.setText("Final Score: " + game.getPlacedPipes());
statusLabel.setVisible(true);
}
else {
if (game.getStyle() == 2) {
statusLabel.setVisible(false);
}
else {
statusLabel.setText("Time Left: ");
statusLabel.setVisible(true);
}
}
// Update the timer bar
if (game.isOver() || (game.getStyle() == 2)) {
timeBar.setVisible(false);
}
else {
timeBar.setValue((int)(game.getTimeRemaining() / (float)game.getTimeLimit() * 100));
timeBar.setVisible(true);
}
// Update the cursor
ImageIcon i;
if (game.isOver()) {
tiles.setCursor(Cursor.getDefaultCursor());
}
else {
if (game.getNextPipe().isValve())
i = new ImageIcon("pipesStart.GIF");
else
i = new ImageIcon("pipes"+ game.getNextPipe().toString() +".GIF");
tiles.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(i.getImage(), new Point(0,0), "pipe"));
}
}
}
I didnt go through all your code but as a hint the function would look like this:
getScore( Pipe p ){
if ( p == null ) return 0;
int res = 1; // size of this pipe
res += getScore(leftPipe);
res += getScore(rightPipe);
...
return res;
}
hope this helps
I think you need to includes the row and col to calculate the pipes that are connected to the main starting pipe
public void connectedPipes(int row, int col){
if(row == null) return 0;
int res = 1; // size of this pipe
res += getScore(leftPipe);
res += getScore(rightPipe);
return res;
}

Implementing ActionListener in the Following Code Inside

I'm having some trouble with my age calculating program on Java. It works fine when I preset the birth year, birth month and birth date values but when I try to have the user input their own birthdate into the text field and then try to work with those values, I just reach a dead-end. I tried asking on Yahoo Answers and the hint I got was "The return value of getActionCommand() is a string while the result is a JLabel. Can you compare them?" I'm not exactly sure what to do with that hint.
Here's what I have and the way I attempted to implement the whole "user input" idea. I'm pretty sure my coding is messy and inefficient, so bear with that please. I'd appreciate any help!
//Date: April 11, 2012
//Description: Calculates the age in terms of days depending on your birthdate.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class AgeCalculator extends Frame implements ActionListener {
JButton equal;
JTextField year, month, day;
JLabel result, first, second, third;
JFrame frame;
JPanel panel;
static int totaldaysalive;
static int daysaliveyr;
static int daysalivem;
static int birthyr;
static int birthm;
static int birthd;
static int currentyr = 2012;
public AgeCalculator(){
gui();
}
public void gui(){
frame = new JFrame ("Age Calculator");
panel = new JPanel(new GridBagLayout());
panel.setBackground(Color.LIGHT_GRAY);
GridBagConstraints x = new GridBagConstraints();
equal = new JButton ("Get Result");
x.insets = new Insets(3,0,3,0);
first = new JLabel("Year ");
x.gridx = 0;
x.gridx = 0;
panel.add(first, x);
year = new JTextField(10);
x.gridx = 5;
x.gridy = 0;
x.gridwidth = 3;
panel.add(year, x);
second = new JLabel ("Month ");
x.gridx = 0;
x.gridy = 1;
panel.add(second,x);
month = new JTextField(10);
x.gridx = 5;
x.gridy = 1;
x.gridwidth = 3;
panel.add(month,x);
third = new JLabel ("Day ");
x.gridx = 0;
x.gridy = 2;
panel.add(third,x);
day = new JTextField(10);
x.gridx = 5;
x.gridy = 2;
x.gridwidth = 3;
panel.add(day,x);
x.gridx = 6;
x.gridy = 3;
panel.add(equal,x);
result = new JLabel ("");
x.gridx = 5;
x.gridy = 5;
panel.add(result,x);
frame.add(panel);
frame.setVisible(true);
frame.setSize(350, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Calc e = new Calc();
equal.addActionListener(e);
year.addActionListener(e);
month.addActionListener(e);
day.addActionListener(e);
}
class Calc implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
birthyr = Integer.parseInt(year.getText());
} catch (NumberFormatException a) {
result.setText("Illegal data for first field.");
result.setForeground(Color.red);
return;
}
try {
birthm = Integer.parseInt(month.getText());
} catch (NumberFormatException a) {
result.setText("Illegal data for second field.");
result.setForeground(Color.red);
return;
}
try {
birthd = Integer.parseInt(day.getText());
} catch (NumberFormatException a) {
result.setText("Illegal data for third field.");
result.setForeground(Color.red);
return;
}
if (e.getActionCommand().equals (equal)){
totaldaysalive = ageCalcYr() + ageCalcM() + birthd;
result.setText(Integer.toString(totaldaysalive));
}
}
public int ageCalcYr(){
for (int i = birthyr; i <= currentyr; i++){
if ((i % 4 == 0) && (!(i % 100 == 0) || (i % 400 == 0))){
daysaliveyr = daysaliveyr + 366;
}
else {
daysaliveyr = daysaliveyr + 365;
}
}
return daysaliveyr;
}
public int ageCalcM(){
if (birthm == 1){
daysalivem = daysalivem + 0;
}
else if (birthm == 2){
daysalivem = daysalivem + 30;
}
else if (birthm == 3){
daysalivem = daysalivem + 60;
}
else if (birthm == 4){
daysalivem = daysalivem + 90;
}
else if (birthm == 5){
daysalivem = daysalivem + 120;
}
else if (birthm == 6){
daysalivem = daysalivem + 150;
}
else if (birthm == 7){
daysalivem = daysalivem + 180;
}
else if (birthm == 8){
daysalivem = daysalivem + 210;
}
else if (birthm == 9){
daysalivem = daysalivem + 240;
}
else if (birthm == 10){
daysalivem = daysalivem + 270;
}
else if (birthm == 11){
daysalivem = daysalivem + 300;
}
else if (birthm == 12){
daysalivem = daysalivem + 330;
}
return daysalivem;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
AgeCalculator gui = new AgeCalculator();
}
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
Fast healing:
if (e.getActionCommand ().equals ("Get Result")) { // equal)) {
totaldaysalive = ageCalcYr () + ageCalcM () + birthd;
result.setText (Integer.toString (totaldaysalive));
}
If you have some time, I can post you 20 improvements.
You extend Frame,
impl. ActionListener, but meanwhile AgeCalculator has a JFrame (which is better in a SwingContext than Frame, which is AWT) and has a seperate Actionlistener which is used.
Remove the declaration, and the the overriding method in the end.
public class AgeCalculator // extends Frame implements ActionListener
There follows a block of visual components and other attributes, the later ones are static - which prohibits using of 2 AgeCalculators on the same JVM. That's surely not a restriction by intent.
Don't make something static to shut up the compiler.
Make everything private, if you aren't sure you want to expose it.
Avoid Attributes where possible.
When will you ever retouch a Label?
JButton equal;
JTextField year, month, day;
JLabel result, ...
...
static int birthd;
static int currentyr = 2012;
Use simplified addition where appropriate:
daysaliveyr += 366;
To calc the days for month, pass the birthyr and the birthm as parameter:
int totaldaysalive = ageCalcYr (birthyr) + ageCalcM (birthm) + birthd;
result.setText (Integer.toString (totaldaysalive));
The livetime of the variable totaldaysalive can be reduced to 2 lines - a very small scope to search for an error, if there is any.
public int ageCalcM (int birthm) {
int daysalivem = 0;
if (birthm == 2) {
daysalivem += 30;
}
else if (birthm == 3) {
daysalivem += 60;
}
In the current state, ageCalcM is a provisorium. Else you could just say daysalivem = (birthm - 1) * 30;
Shorter code:
public int ageCalcM (int birthm) {
if (birthm == 2) {
return 30;
}
else if (birthm == 3) {
return 60;
}
However, such mass manipulation in stupid repetition can be solved with an simple array:
public int ageCalcM (int birthm) {
int[] mdays = {0, 30, 60, 90, ...};
return mdays [birthm];
}
In the main-Method you create an instance 'gui', which is never used. This is all you need:
public static void main (String [] args) {
new AgeCalculator ();
}
Gui, btw. is a bad name, if you already have a method of said name.
Since that method is never used, just move the whole thing into the ctor.
year/month/date don't need the ActionListener.
Other layouts are much better suited.
We need another calender reform to make your program work.
Input should not only be checked to be int, but valid month etc.
The actual date isn't used.
What is left?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class AgeCalculator
{
JTextField year, month, day;
JLabel result;
public AgeCalculator () {
JFrame frame = new JFrame ("Age Calculator");
JPanel panel = new JPanel (new GridBagLayout ());
panel.setBackground (Color.LIGHT_GRAY);
GridBagConstraints x = new GridBagConstraints ();
JButton equal = new JButton ("Get Result");
x.insets = new Insets (3, 0, 3, 0);
JLabel first = new JLabel ("Year ");
// two times gridx = 0 here?
x.gridx = 0;
x.gridx = 0;
panel.add (first, x);
year = new JTextField (10);
x.gridx = 5;
x.gridy = 0;
x.gridwidth = 3;
panel.add (year, x);
JLabel second = new JLabel ("Month ");
x.gridx = 0;
x.gridy = 1;
panel.add (second, x);
month = new JTextField (10);
x.gridx = 5;
x.gridy = 1;
x.gridwidth = 3;
panel.add (month, x);
JLabel third = new JLabel ("Day ");
x.gridx = 0;
x.gridy = 2;
panel.add (third, x);
day = new JTextField (10);
x.gridx = 5;
x.gridy = 2;
x.gridwidth = 3;
panel.add (day, x);
x.gridx = 6;
x.gridy = 3;
panel.add (equal, x);
result = new JLabel ("");
x.gridx = 5;
x.gridy = 5;
panel.add (result, x);
frame.add (panel);
frame.setVisible (true);
frame.setSize (350, 350);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
Calc e = new Calc ();
equal.addActionListener (e);
}
class Calc implements ActionListener {
public void actionPerformed (ActionEvent e) {
int birthyr;
int birthm;
int birthd;
try {
birthyr = Integer.parseInt (year.getText ());
} catch (NumberFormatException a) {
result.setText ("Illegal data for first field.");
result.setForeground (Color.red);
return;
}
try {
birthm = Integer.parseInt (month.getText ());
} catch (NumberFormatException a) {
result.setText ("Illegal data for second field.");
result.setForeground (Color.red);
return;
}
try {
birthd = Integer.parseInt (day.getText ());
} catch (NumberFormatException a) {
result.setText ("Illegal data for third field.");
result.setForeground (Color.red);
return;
}
if (e.getActionCommand ().equals ("Get Result")) { // equal)) {
int totaldaysalive = ageCalcYr (birthyr) + ageCalcM (birthm) + birthd;
result.setText (Integer.toString (totaldaysalive));
}
}
public int ageCalcYr (int birthyr) {
int currentyr = 2012;
int daysaliveyr = 0;
for (int i = birthyr; i <= currentyr; i++) {
if ((i % 4 == 0) && (! (i % 100 == 0) || (i % 400 == 0))) {
daysaliveyr += 366;
}
else {
daysaliveyr += 365;
}
}
return daysaliveyr;
}
public int ageCalcM (int birthm) {
int[] mdays = {0, 30, 60, 90, 120};
return mdays [birthm];
}
}
public static void main (String [] args) {
new AgeCalculator ();
}
}
Since you're using a button to kick off the calculation, only register an action listener on that button. Inside the action performed method read, parse and calculate the age in days.
I think you want to do equal.addMouseListener(e). Of course you'll have to change Calc to implement MouseListener. You'll probably only have to actually write the mouseClicked(MouseEvent) method. All of the others are for more specific things than what you're after.
That will respond to a click event on your button. I don't think you want any other listeners. If so, they should be KeyListeners or something other than ActionListeners.
On a side note, It's hard for me to see because your indentation is off, but I can't really tell why your int fields are static. I think that's probably unnecessary.

Categories