Noelle
Noelle

Reputation: 21

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
    }
}

Upvotes: 2

Views: 1481

Answers (3)

user unknown
user unknown

Reputation: 36229

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.

  1. You extend Frame,
  2. 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.
  3. 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.

  1. Don't make something static to shut up the compiler.
  2. Make everything private, if you aren't sure you want to expose it.
  3. Avoid Attributes where possible.
  4. When will you ever retouch a Label?
    JButton equal;
    JTextField year, month, day;
    JLabel result, ...

    ...
    static int birthd;
    static int currentyr = 2012; 
  1. Use simplified addition where appropriate:

    daysaliveyr += 366;
    
  2. 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));

  3. 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;
        }
    
  4. In the current state, ageCalcM is a provisorium. Else you could just say daysalivem = (birthm - 1) * 30;

  5. Shorter code:

    public int ageCalcM (int birthm) {
        if (birthm == 2) {
            return 30;
        }
        else if (birthm == 3) {
            return 60;
        }
    
  6. 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];
    }
    
  7. 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 (); }

  8. Gui, btw. is a bad name, if you already have a method of said name.

  9. Since that method is never used, just move the whole thing into the ctor.
  10. year/month/date don't need the ActionListener.
  11. Other layouts are much better suited.
  12. We need another calender reform to make your program work.
  13. Input should not only be checked to be int, but valid month etc.
  14. 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 ();
    }
}

Upvotes: 3

Tim Pote
Tim Pote

Reputation: 28029

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.

Upvotes: 0

Tommy B
Tommy B

Reputation: 185

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.

Upvotes: 0

Related Questions