-1

I looked through some of the other asked questions but did not see anything with my exact issue. Here's the problem, I have this Java GUI BMI calculator and everything works except that I get back infinity for the BMI. The odd thing is that when I included output statements to the BMI displays just fine on the console. The console and the GUI calculator are using the same hp.getBMI() so why would one get the correct output and the other show infinity. Forgive me if my code is sloppy, it's my first Java program and I'm not quite finished editing it. Thanks in advance.

public class HealthProfile 
{
    private int age;
    private double height, heightFt, heightIn, weight, BMI, maxHR;
    private String name, category;

    //parameterized constructor
    public HealthProfile(String name, int age, double heightFt, double heightIn, double weight)
    {
        this.name = name;
        this.age = age;
        this.heightFt = heightFt;
        this.heightIn = heightIn;
        this.weight = weight;

    }
    //default constructor
    public HealthProfile()
    {
        this("",0,0,0,0);
    }

    public double getHeight()
    {
        height = heightIn + heightFt * 12;  
        return height;
    }
    public double getBMI()
    {
        BMI = weight * 703 / (height * height);
        return BMI;
    }

    public double getMaxHR()
    {
        maxHR = 220 - age;
        return maxHR;
    }
    public String getCategory()
    {
        if (BMI < 18.5)
            category = "Underweight";
        else if (BMI >= 18.5 && BMI <= 24.9)
            category = "Normal";
        else if (BMI >= 25 && BMI <= 29.9)
            category = "Overweight";
        else
            category = "Obese";
        return category;
    }

}

HealthProfile_GUI.java:

public class HealthProfile_GUI extends JFrame implements ActionListener 
{
        //Private textfields for name, age, height (feet), height (inches),
        //weight, BMI, category, and max heart rate
        private JTextField txtName = new JTextField(25);
        private JTextField txtAge = new JTextField(3);
        ...

        //Private JLabels for those textfields
        private JLabel lblName = new JLabel("Name");
        ...

        private JButton btnCalc = new JButton("Calcualte BMI");
        private JButton btnClear = new JButton("Clear");
        private HealthProfile hp;

        public HealthProfile_GUI()
        {
            setTitle("Health Profile");
            setSize(400,500);
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            Container c = getContentPane();
            c.setLayout(new GridLayout(9,2,10,10));

            c.add(lblName);
            c.add(txtName);
            ...and add all the other text fields and labels

            btnCalc.addActionListener(this);
            btnClear.addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent ae)
        {
            boolean notEmpty = true;
            if(hp == null)
            {
                hp = new HealthProfile();
            }
            if (ae.getSource() == btnCalc) 
            {
                System.out.println("Calculating BMI");

                if(txtName.getText().equals("") || txtName.getText().isEmpty()) 
                {
                    JOptionPane.showMessageDialog(null,"Name is required");
                    notEmpty = false;
                }
                if(txtAge.getText().equals("") || txtAge.getText().isEmpty())
                {
                    JOptionPane.showMessageDialog(null,"Age is required");
                    notEmpty = false;
                }
                if(txtHeightFt.getText().equals("") || txtHeightFt.getText().isEmpty()) 
                {
                    JOptionPane.showMessageDialog(null,  "Height (Feet) is required");
                    notEmpty = false;
                }
                if(txtHeightIn.getText().equals("") || txtHeightIn.getText().isEmpty()) 
                {
                    JOptionPane.showMessageDialog(null,  "Height (Inches) is required");
                    notEmpty = false;
                }
                if(txtWeight.getText().equals("") || txtWeight.getText().isEmpty()) 
                {
                    JOptionPane.showMessageDialog(null,  "Weight is required");
                    notEmpty = false;
                }
                if (notEmpty == true) 
                {
                    hp.setName(txtName.getText());
                    hp.setAge(Integer.parseInt(txtAge.getText()));
                    hp.setHeightFt(Double.parseDouble(txtHeightFt.getText()));
                    hp.setHeightIn(Double.parseDouble(txtHeightIn.getText()));
                    hp.setWeight(Double.parseDouble(txtWeight.getText()));
                    txtBMI.setText(String.format("%.2f", hp.getBMI()));
                    txtCat.setText(hp.getCategory());
                    txtMaxHR.setText(String.format("%.0f", hp.getMaxHR()));
                    System.out.println(hp.getWeight());
                    System.out.println(hp.getHeight());
                    System.out.println(hp.getHeightFt());
                    System.out.println(hp.getHeightIn());
                    System.out.println(hp.getBMI());
                }
            }
            else if(ae.getSource() == btnClear)
            {
                txtName.setText("");
                txtAge.setText("");
                txtHeightFt.setText("");
                txtHeightIn.setText("");
                txtWeight.setText("");
                txtBMI.setText("");
                txtCat.setText("");
                txtMaxHR.setText("");
            }                       
        }                   
}

The main class, which simply runs the GUI

public class HealthProfileMain {

    public static void main(String[] args) 
    {
        HealthProfile_GUI hp = new HealthProfile_GUI();
    }
}
Paul R
  • 208,748
  • 37
  • 389
  • 560
Chris
  • 3
  • 1
  • The fact that your default constructor sets everything to 0 is odd. Why should there be a default constructor? Also, in if statements, you don't need to do `if (someVar == true)` if `someVar` is a boolean. Just do `if (someVar)` – user May 17 '20 at 18:54
  • Does this answer your question? [Why doesn't Java throw an Exception when dividing by 0.0?](https://stackoverflow.com/questions/2381544/why-doesnt-java-throw-an-exception-when-dividing-by-0-0) – Arvind Kumar Avinash May 17 '20 at 18:58

2 Answers2

1

The method getBMI() does not compute the height: it's only set by getHeight(), which is not called before the first call to getBMI().

That is, your event listener correctly reads the heightFt and heightIn values, but height is still zero. It may be wise to update the height as well, each tim you read heightFt and heightIn.

So, the first call to getBMI() produces a division by zero (hence infinity, as it's not an error in Java floating point), and the second call to getBMI() gets the correct value of height, hence a correct result.

  • Yup, that was it. I suppose that I assumed the `getBMI()` method could be called at anytime to retrieve the `BMI` as long as the `HeightFt` and `HeightIn` had passed the values to `Height`. Thank you. – Chris May 17 '20 at 19:08
0

When you call getBMI() the first time the height has not been set. But before the second call you called getHeight(), which sets the correct value for height.

Sam
  • 144
  • 3