calculator.java

calc.java

import java.awt.*;

public class calc extends Frame {

Button[] b = new Button[25];
Pan tf = new Pan(1);
Font f = new Font("TimesRoman", Font.BOLD, 14);
double n = 0;
int op;
boolean flag = false;
Toolkit tool;

public static void main(String[] args) {
new calc();
}

public calc() {
setTitle("Calculator");
tool = getToolkit();
setBackground(new Color(38, 104, 165));
setForeground(new Color(255, 255, 255));
setResizable(false);
setIconImage(tool.getImage(GetResources("ico.gif")));
resize(350, 400);
setLayout(null);
tf.setBounds(50, 50, 240, 25);
tf.setFont(f);
tf.setForeground(new Color(0, 0, 0));
tf.setBackground(new Color(150, 150, 255));
tf.setText("0");
for (int i = 0; i < 25; i++) {
String s = "" + i;
if (i >= 10) {
switch (i) {
case 10:
s = "+";
break;
case 11:
s ="-";break;
case 12:
s = "*";
break;
case 13:
s = "/";
break;
case 14:
s = "=";
break;
case 15:
s = "C";
break;
case 16:
s = "sqrt";
break;
case 17:
s = "%";
break;
case 18:
s = "sin";
break;
case 19:
s = "cos";
break;
case 20:
s = "tan";
break;
case 21:
s = "Exp";
break;
case 22:
s = "Log";
break;
case 23:
s = "";
break;
case 24:
s = "";
break;
}
}
b[i] = new Button(s);
b[i].setFont(new Font("TimesRoman", 1, 20));
b[i].setForeground(new Color(0, 0, 0));
b[i].setBackground(new Color(255, 255, 222));
if (i < 5) {
b[i].setBounds(50 + 50 * i, 100, 40, 40);
} else if (i < 10) {
b[i].setBounds(50 + 50 * (i - 5), 150, 40, 40);
} else if (i < 15) {
b[i].setBounds(50 + 50 * (i - 10), 200, 40, 40);
} else if (i < 20) {
b[i].setBounds(50 + 50 * (i - 15), 250, 40, 40);
} else {
b[i].setBounds(50 + 50 * (i - 20), 300, 40, 40);
}
}
Dimension res = tool.getScreenSize();
move((int) ((res.width - 400) / 2 + 100), (int) ((res.height - 400) / 2 + 100));
setVisible(true);
}

public java.net.URL GetResources(String s) {
return this.getClass().getResource(s);
}

public boolean handleEvent(Event e) {
if (e.id == Event.WINDOW_DESTROY) {
dispose();
}
if (e.id == Event.ACTION_EVENT) {
for (int i = 0; i < 10; i++) {
if ((e.target).equals(b[i])) {
String s = tf.getText();
if (s.equals("0")) {
s = "" + i;
} else if (flag) {
s = "" + i;
flag = false;
} else {
s += i;
}
tf.setText(s);
return true;
}
}
if ((e.target).equals(b[10])) {
n = Double.parseDouble(tf.getText());
op = 10;
flag = true;
return true;
}
if ((e.target).equals(b[11])) {
n = Double.parseDouble(tf.getText());
op = 11;
flag = true;
return true;
}
if ((e.target).equals(b[12])) {
n = Double.parseDouble(tf.getText());
op = 12;
flag = true;
return true;
}
if ((e.target).equals(b[13])) {
n = Double.parseDouble(tf.getText());
op = 13;
flag = true;
return true;
}
if ((e.target).equals(b[14])) {
switch (op) {
case 10:
n += Double.parseDouble(tf.getText());
break;
case 11:
n -= Double.parseDouble(tf.getText());
break;
case 12:
n *= Double.parseDouble(tf.getText());
break;
case 13:
n /= Double.parseDouble(
tf.getText());
break;
case 17:
n %= Double.parseDouble(tf.getText());
break;
}
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length() - 2);
}
tf.setText(ss);
return true;
}
if ((e.target).equals(b[15])) {
tf.setText("0");
flag = false;
return true;
}
if ((e.target).equals(b[16])) {
double d = Double.parseDouble(tf.getText());
if (d >= 0) {
n = Math.sqrt(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.
length()
- 2);
}
tf.setText(ss);
}
return true;
}
if ((e.target).equals(b[17])) {
n = Double.parseDouble(tf.getText());
op = 17;
flag = true;
return true;
}
if ((e.target).equals(b[18])) {
double d = Double.parseDouble(tf.getText());
n = Math.sin(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length()
- 2);
}
tf.setText(ss);
return true;
}
if ((e.target).equals(b[19])) {
double d = Double.parseDouble(tf.getText());
n = Math.cos(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length()
- 2);
}
tf.setText(ss);
return true;
}
if ((e.target).equals(b[20])) {
double d = Double.parseDouble(tf.getText());
n = Math.tan(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length() - 2);
}
tf.setText(ss);
return true;
}
if ((e.target).equals(b[21])) {
double d = Double.parseDouble(tf.getText());
n = Math.exp(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length() - 2);
}
tf.setText(ss);
return true;
}
if ((e.target).equals(b[22])) {
double d = Double.parseDouble(tf.getText());
if (d > 0) {
n = Math.log(d);
String ss = "" + n;
if (ss.endsWith(".0")) {
ss = ss.substring(0, ss.length() - 2);
}
tf.setText(ss);
}
return true;
}
}
return false;
}
}


Pan.java

class Pan extends Panels {

public Font f = new Font("Helvetica", 1, 18);
FontMetrics fm = getFontMetrics(f);
public String s = "";
private int tip;

public Pan() {
super();
}

public Pan(int tip) {
this();
this.tip = tip;
}

public void setText(String s) {
this.s = s;
repaint();
}

public String getText() {
return s;
}

public void paint(Graphics g) {
super.paint(g);
g.setFont(f);
if (tip == 1) {
g.setColor(Color.white);
g.drawString(s, size().width - fm.stringWidth(s) - 6, 20);
} else {
g.setColor(Color.black);
g.drawString(s, 10, 20);
}
}
}


Panels.java

class Panels extends Panel {

public Image im, im1;

public Panels(Image im) {
this.im = im;
}

public Panels() {
}

public void update(Graphics g) {
paint(g);
}

public void paint(Graphics g) {
super.paint(g);
Dimension dimension = size();
im1 = createImage(dimension.width, dimension.height);
pan(im1.getGraphics());
g.drawImage(im1, 0, 0, this);
}

public void pan(Graphics g) {
Dimension dimension = size();
int w = dimension.width;
int h = dimension.height;
Color color = getBackground();
g.setColor(color);
g.fillRect(0, 0, w, h);
if (im != null) {
for (int k = 0; k < w; k += im.getWidth(this)) {
for (int l = 0; l < h; l += im.getHeight(this)) {
g.drawImage(im, k, l, this);
}
}
}
g.setColor(color.brighter());
g.drawRect(1, 1, w - 2, h - 2);
g.setColor(color.darker());
g.drawRect(0, 0, w - 2, h - 2);
}
}

• Welcome to Code Review. Please add a few sentences describing your code, from a user's perspective. – Raimund Krämer Jan 22 '18 at 11:45

• Class names should be spelled with capital letters (also referred to as PascalCase, or UpperCamelCase). Your calc class starts with a lowercase letter. Consistency with capitalizing all class names is important for readability, and to be able to distinguish classes from variables.
• You have a lot of abbreviations in your code. Abbreviating class and variable names (or worse: using single letters for them) can be tempting when writing a longer program, in order to have to write less code, but especially then it is important to write longer names that tell you what they mean. A variable name should tell you what it contains. As an example, Button[] b = new Button[25]; should be Button[] buttons = new Button[25];.
• Your indentation is off in a few places, especially in your switch statement. That can be very confusing when reading the code. If you use an IDE to edit your code, it probably can format the code for you automatically.
• You have a very confusing class hierarchy. The class names are all different versions of each other, sometimes singular, sometimes plural, sometimes abbreviated. (Pan extends Panels, which extends Panel.) Either try to think of better names for these, or rethink whether they should really extend each other at all. Ask yourself: Is a Pan also a kind of Panels? Is a Panels a kind of Panel?
• You are iterating over your array with a hardcoded bound: for (int i = 0; i < 25; i++) { ... }. Simply removing a button and reducing the array to a length of 24 will cause your program to crash with a IndexOutOfBoundsException. Instead, access the length of the array dynamically: myArray.length will give you its length. So the loop should look like this: for (int i = 0; i < b.length; i++) { ... }.
• You are doing lots of things in your constructor, including starting the program (meaning your actual calculator GUI). Better move the code into a method (or better: multiple methods, divided into parts of logically related code) and call the method(s) from within your constructor. Also, use a public method to initialize and start the program after creating the instance. If the code starts a GUI from just doing new calc();, that is unexpected. Rather do this: new calc().show(); or something similar, so that you always know that it will not only create an object, but also show the GUI.

Since it looks like a 'fifth java lesson' excercise, I'll review based on that.

Abbreviations

95% percent of the time, using abbreviations worsens the readability of the code. "tf", "b", "n", "op" for instance. If I'm reading the code and have to scroll up to figure what what 'tf' actually means, it prohibits the 'reading flow'.

Also: Class names should be nouns - and as already mentioned in another post: they should be singular. Methods should contain a verb.

naming stuff

Always give "things" a proper name, the clearer the better. You have a method calc(). First I thought, things will be calculated here. But it actually initializes the gui. Sooo, initializeGUI would have helped here.

Why is that important: Depending on your task you have to do, you spend more time reading code than writing code.

Do one thing

It's important, that a method does one thing. The more it does, the more complicated it will be to understand. The handleEvent() method for instance, does close the window and performs calculations.

Java Coding Conventions

http://www.oracle.com/technetwork/java/codeconvtoc-136057.html

Raimund already mentioned stuff like PascalCase. Many things come naturally, but I think it's a good read and you can avoid making a habit of non-conventions.

main method

Usually, the main method is put at the end of a class.

scopes

99% of the time, member variables should be declared private. I would recommend to make a habit of it. If you decide to make a variable more public, you need to have a good reason for it.

@Override

You've overridden some methods from the super class, always annotate them with the @Override annotation. First, this shows the reader, that it's overridden from a superclass or an interface, but also if you'd somehow mess up a refactoring, the compiler will tell you "You got an @Override annotation, but actually, it is not overridden".

Hope this helps,

slowy

• You were (understandably) tricked by the names and naming scheme. calc() is the constructor, not a method. – Raimund Krämer Jan 22 '18 at 13:10
• Don't mix up override and overwrite. Overwrite implies a change of value, while override means hiding, or overruling. – Raimund Krämer Jan 22 '18 at 13:21
• @RaimundKrämer : Oh for f's sake, thanks mate xD - but what more proof do we need, that applying the coding convetions is a good thing? ;D – slowy Jan 22 '18 at 13:23
• @RaimundKrämer And thx for pointing out "overwrite/overwridden/overwrite/overridden (I think that's correct)". I think I wrote that wrong all my life and you're the first pointing that out. – slowy Jan 22 '18 at 13:27