patternjavaMinor
Simple calculator implemented with lambdas
Viewed 0 times
lambdassimplewithimplementedcalculator
Problem
I was searching for a way to exercise the Java 8 concepts I've been learning, especially pertaining to Lambdas. Incidentally, I hadn't used any swing in a while and wanted a refresher. This is the result of these two pursuits.
```
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class EquationCalculator {
static interface Equation {
double compute(double val1, double val2);
}
public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> new EquationCalculator());
}
public EquationCalculator() {
JFrame frame = new JFrame("Basic Operations");
JPanel panel = new JPanel(new GridLayout(1, 3));
JTextField first = new JTextField("2");
JTextField second = new JTextField("3");
JComboBox calculate = new JComboBox<>();
calculate.addItem("Sum");
calculate.addItem("Difference");
calculate.addItem("Product");
calculate.addItem("Quotient");
calculate.addItem("Exponent");
calculate.addActionListener(
e -> JOptionPane.showMessageDialog(
null, "The result is " +
calculate(
String.valueOf(calculate.getSelectedItem()),
Double.parseDouble(first.getText()),
Double.parseDouble(second.getText())
),
"Result", JOptionPane.INFORMATION_
```
import java.awt.GridLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
public class EquationCalculator {
static interface Equation {
double compute(double val1, double val2);
}
public static void main(String[] args) {
try {
for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(() -> new EquationCalculator());
}
public EquationCalculator() {
JFrame frame = new JFrame("Basic Operations");
JPanel panel = new JPanel(new GridLayout(1, 3));
JTextField first = new JTextField("2");
JTextField second = new JTextField("3");
JComboBox calculate = new JComboBox<>();
calculate.addItem("Sum");
calculate.addItem("Difference");
calculate.addItem("Product");
calculate.addItem("Quotient");
calculate.addItem("Exponent");
calculate.addActionListener(
e -> JOptionPane.showMessageDialog(
null, "The result is " +
calculate(
String.valueOf(calculate.getSelectedItem()),
Double.parseDouble(first.getText()),
Double.parseDouble(second.getText())
),
"Result", JOptionPane.INFORMATION_
Solution
Don't use String labels of GUI elements in flow control
It's not good to use the String labels of GUI elements to make decisions.
It would be slightly better if you made
An
With this, you could create the
Change the call to
And simplify
Avoid pointless evaluations
In
This is pointless and wasteful.
Simplify lambdas with method references
These lambdas can be replaced with method references:
Like this:
Pointless to print stack trace in
If an exception is thrown in
a stack trace will be printed on the console.
There's no need to catch an exception and do the same manually.
Also beware,
it's not a good practice to catch
It's recommended to catch specific exceptions,
both to signal to readers the things that can possibly go wrong,
and also to avoid truly unexpected exceptions getting caught by the blanket
It's not good to use the String labels of GUI elements to make decisions.
It would be slightly better if you made
"Sum", "Difference", ... global constants, but only slightly.An
enum would be better for this purpose:enum Operation {
Sum("Sum", (x, y) -> x + y),
Difference("Difference", (x, y) -> x - y),
Product("Product", (x, y) -> x * y),
Quotient("Quotient", (x, y) -> x / y),
Exponent("Exponent", Math::pow)
;
private final String label;
private final Equation equation;
private Operation(String label, Equation equation) {
this.label = label;
this.equation = equation;
}
@Override
public String toString() {
return label;
}
}With this, you could create the
JComboBox with Operation items instead of String:JComboBox calculate = new JComboBox<>();
calculate.addItem(Operation.Sum);
calculate.addItem(Operation.Difference);
calculate.addItem(Operation.Product);
calculate.addItem(Operation.Quotient);
calculate.addItem(Operation.Exponent);Change the call to
calculate to this:calculate(
((Operation) calculate.getSelectedItem()).equation,
Double.parseDouble(first.getText()),
Double.parseDouble(second.getText())
),And simplify
calculate itself to this:public static double calculate(Equation operation, double val1, double val2) {
return operation.compute(val1, val2);
}Avoid pointless evaluations
In
calculate, you declare all the equation types at the top but only use one of them.This is pointless and wasteful.
Simplify lambdas with method references
These lambdas can be replaced with method references:
SwingUtilities.invokeLater(() -> new EquationCalculator());
// ...
Equation exponentiate = (alpha, beta) -> Math.pow(alpha, beta);Like this:
SwingUtilities.invokeLater(EquationCalculator::new);
// ...
Equation exponentiate = Math::pow;Pointless to print stack trace in
mainIf an exception is thrown in
main,a stack trace will be printed on the console.
There's no need to catch an exception and do the same manually.
Also beware,
it's not a good practice to catch
Exception.It's recommended to catch specific exceptions,
both to signal to readers the things that can possibly go wrong,
and also to avoid truly unexpected exceptions getting caught by the blanket
catch.Code Snippets
enum Operation {
Sum("Sum", (x, y) -> x + y),
Difference("Difference", (x, y) -> x - y),
Product("Product", (x, y) -> x * y),
Quotient("Quotient", (x, y) -> x / y),
Exponent("Exponent", Math::pow)
;
private final String label;
private final Equation equation;
private Operation(String label, Equation equation) {
this.label = label;
this.equation = equation;
}
@Override
public String toString() {
return label;
}
}JComboBox<Operation> calculate = new JComboBox<>();
calculate.addItem(Operation.Sum);
calculate.addItem(Operation.Difference);
calculate.addItem(Operation.Product);
calculate.addItem(Operation.Quotient);
calculate.addItem(Operation.Exponent);calculate(
((Operation) calculate.getSelectedItem()).equation,
Double.parseDouble(first.getText()),
Double.parseDouble(second.getText())
),public static double calculate(Equation operation, double val1, double val2) {
return operation.compute(val1, val2);
}SwingUtilities.invokeLater(() -> new EquationCalculator());
// ...
Equation exponentiate = (alpha, beta) -> Math.pow(alpha, beta);Context
StackExchange Code Review Q#82853, answer score: 8
Revisions (0)
No revisions yet.