This is my first question here and I'd like to get some feedback. The program works but I'm not sure the classes I've used are right.
First, a class to calculate the Body Mass Index from a double (kgs) and an integer (height in cm):
//Data taken from https://codereview.stackexchange.com/questions/216933/java-swing-exercise-bmi-calculator
//NavigableMap idea taken from https://codereview.stackexchange.com/questions/142708/school-grading-string-calculator/142752#142752
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class PersonHealthData {
private final double weight; //Kg.
private final int height; //cm.
private static final NavigableMap<Double, String> grades = new TreeMap<>();
static {
grades.put(0.0, "Insuficient Weight");
grades.put(18.5, "Normal Wight");
grades.put(24.9, "Overweight Grade 1");
grades.put(26.9, "Overweight Grade 2: Probesity");
grades.put(29.9, "Obesity Grade 1");
grades.put(34.9, "Obesity Grade 2");
grades.put(39.9, "Obesity Grade 3: Morbid");
grades.put(49.9, "Obesity Grade 4: Extreme");
}
public PersonHealthData(double weight, int height) {
this.weight = weight;
this.height = height;
}
public double getWeight() {
return weight;
}
public int getHeight() {
return height;
}
public double getBMI() {
double heightMeters = height / 100.0;
return weight / (double) (heightMeters * heightMeters);
}
public String getGrade() {
Map.Entry<Double, String> gradeEntry = grades.floorEntry(getBMI());
if (gradeEntry == null) {
return "Incorrect Data";
}
return gradeEntry.getValue();
}
}
The second class is the Main program (creates the interface and acts like a controller I guess)
import javax.swing.*;
import java.awt.*;
public class MainProgram {
private final JFrame window;
private final EntryPanel dataEntry;
private final ResultPanel results;
MainProgram() {
window = new JFrame("BMI CAlculator");
window.setLayout(new GridLayout(0, 1));
dataEntry = new EntryPanel(this);
window.add(dataEntry.getPanel());
results = new ResultPanel();
window.add(results.getPanel());
window.pack();
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
}
public void show() {
window.setVisible(true);
}
public static void main(String[] args) {
MainProgram mainProgram;
mainProgram = new MainProgram();
mainProgram.show();
}
public void action() {
double weight;
try {
weight = Double.parseDouble(dataEntry.getStringWeight());
} catch (NumberFormatException e) {
results.error("Weight input is not a number");
return;
}
int height;
try {
height = Integer.parseInt(dataEntry.getStringHeight());
} catch (NumberFormatException e) {
results.error("Height input is not a number");
return;
}
PersonHealthData data = new PersonHealthData(weight, height);
results.setResults(String.format("Your BMI is: %.2f", data.getBMI()), data.getGrade());
}
}
And two classes to practice Swing components and listeners. The first one is an input Panel:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class EntryPanel {
private final JPanel panel;
private final JPanel panelSliders;
private final JPanel panelInput;
private final JTextField textWeight;
private final JTextField textHeight;
private final MainProgram mainProgram;
private final JSlider sliderWeight;
private final JSlider sliderHeight;
EntryPanel(MainProgram mainProgram) {
this.mainProgram = mainProgram;
panel = new JPanel(new GridLayout(0, 1));
panelSliders = new JPanel(new GridLayout(0, 2));
sliderWeight = new JSlider();
sliderWeight.setMinimum(10);
sliderWeight.setMaximum(200);
panelSliders.add(sliderWeight);
panelSliders.add(new JLabel("Weight"));
sliderHeight = new JSlider();
sliderHeight.setMinimum(10);
sliderHeight.setMaximum(270);
panelSliders.add(sliderHeight);
panelSliders.add(new JLabel("Height"));
panelSliders.setBorder(new EmptyBorder(10, 10, 10, 10));
panel.add(panelSliders);
panelInput = new JPanel(new GridLayout(0, 3, 10, 10));
panelInput.setBorder(new EmptyBorder(10, 10, 10, 10));
panelInput.add(new JLabel("Weight"));
textWeight = new JTextField();
textWeight.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
mainProgram.action();
}
});
textWeight.setHorizontalAlignment(SwingConstants.RIGHT);
panelInput.add(textWeight);
panelInput.add(new JLabel("kg."));
panelInput.add(new JLabel("Height"));
textHeight = new JTextField();
textHeight.setHorizontalAlignment(SwingConstants.RIGHT);
textHeight.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
super.keyReleased(e);
mainProgram.action();
}
});
panelInput.add(textHeight);
panelInput.add(new JLabel("cm."));
sliderWeight.addChangeListener(e -> {
textWeight.setText("" + sliderWeight.getValue());
mainProgram.action();
});
sliderHeight.addChangeListener(e -> {
textHeight.setText("" + sliderHeight.getValue());
mainProgram.action();
});
panel.add(panelInput);
}
public JPanel getPanel() {
return panel;
}
public String getStringWeight() {
return textWeight.getText();
}
public String getStringHeight() {
return textHeight.getText();
}
}
And the second one is used to show the results:
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class ResultPanel {
private final JPanel panel;
private final JLabel BMI;
private final JLabel information;
ResultPanel() {
panel = new JPanel();
panel.setLayout(new GridLayout(0, 1, 10, 10));
panel.setBorder(new EmptyBorder(10, 10, 10, 10));
BMI = new JLabel("Enter your weight and height in centimeters.");
BMI.setHorizontalAlignment(SwingConstants.CENTER);
information = new JLabel("");
information.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(BMI);
panel.add(information);
}
public JPanel getPanel() {
return panel;
}
public void setResults(String IMC, String information) {
this.BMI.setText(IMC);
this.BMI.setForeground(Color.BLACK);
this.information.setText(information);
}
public void error(String s) {
this.BMI.setText(s);
this.BMI.setForeground(Color.RED);
this.information.setText("");
}
}
No Unit Tests because We've not gone so far in my class.
Any advice or comment will be very appreciated and welcome.