I am coding a java-based calculator and just wanted to show any value over 100,000 into scientific notation format. I'm wondering how you would display the number, change it back into long form for calculations on the back-end, and then display it once again in clean, scientific notation. I would like it to be as simple as possible as I am not a master by any means at java, I have just started learning it about two months ago.
package javacalc;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import java.text.DecimalFormat;
public class CalcGUI extends JFrame implements ActionListener {
final static String PROJ_TITLE = "Calculator";
final static String PROJ_AUTHORS = String.format("Jaren Browne%nKevin Miller");
final static int[] PROJ_WINDOW_SIZE = {490, 650};
final static int[] PROJ_WINDOW_LOCATION = {300, 300};
GridBagConstraints gbcCalcPanel = new GridBagConstraints();
GridBagConstraints gbcButtonPanel = new GridBagConstraints();
JPanel calcPanel = new JPanel();
JTextField upperDisplay;
JTextField lowerDisplay;
private static char operation;
private static double firstNumber = 0;
private static double secondNumber = 0;
private static double mem = 0;
private static boolean clearScreen = true;
DecimalFormat df = new DecimalFormat("0.##############");
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
String displayString = upperDisplay.getText();
if (digitTest(command)) {
updateDisplay(command);
return;
}
// Basic arithmetic
if (command.equals("=") || command.equals("+") || command.equals("-") || command.equals("x") || command.equals("÷") || command.equals("%")) {
clearScreen = true;
try {
if (!calculate(Double.parseDouble(displayString))) {
updateDisplay("DIV / 0");
reset();
return;
}
} catch (NumberFormatException ex) {}
updateDisplay("" + df.format(secondNumber));
clearScreen = true;
operation = command.charAt(0);
firstNumber = secondNumber;
return;
}
switch (command) {
case ".": // decimal
updateDisplay(".");
break;
// Pos/Neg pressed
case "+/-":
clearScreen = true;
if (!upperDisplay.getText().equals("0")) {
try {
double inverse = Double.parseDouble(displayString);
inverse *= -1;
updateDisplay(df.format(inverse));
} catch (NumberFormatException ex) {
updateDisplay("0");
}
}
break;
// Clear pressed
case "CE":
reset();
updateDisplay("0");
break;
// Backspace pressed
case "<-":
if (clearScreen) {
updateDisplay("0");
} else {
deletePressed();
}
break;
case "MC":
mem = 0;
break;
case "MR":
clearScreen = true;
updateDisplay("" + df.format(mem));
clearScreen = true;
break;
case "M+":
try {
mem += Double.parseDouble(displayString);
} catch (NumberFormatException ex) {}
break;
case "M-":
try {
mem -= Double.parseDouble(displayString);
} catch (NumberFormatException ex) {}
break;
case "π":
clearScreen = true;
updateDisplay(String.valueOf(Math.PI));
clearScreen = true;
break;
case "xⁿ":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = '^';
firstNumber = secondNumber;
clearScreen = true;
break;
case "√":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = '√';
firstNumber = secondNumber;
clearScreen = true;
break;
case "ⁿ√":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = '&';
firstNumber = secondNumber;
clearScreen = true;
break;
case "sin":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 'S';
firstNumber = secondNumber;
clearScreen = true;
break;
case "cos":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 'C';
firstNumber = secondNumber;
clearScreen = true;
break;
case "tan":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 'T';
firstNumber = secondNumber;
clearScreen = true;
break;
case "sin‾¹":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 's';
firstNumber = secondNumber;
clearScreen = true;
break;
case "cos‾¹":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 'c';
firstNumber = secondNumber;
clearScreen = true;
break;
case "tan‾¹":
clearScreen = true;
calculate(Double.parseDouble(displayString));
updateDisplay("" + df.format(secondNumber));
operation = 't';
firstNumber = secondNumber;
clearScreen = true;
break;
}
}
private boolean calculate(double displayNumber) {
secondNumber = displayNumber;
switch (operation) {
case '+': // Addition
secondNumber += firstNumber;
break;
case '-': // Subtraction
secondNumber = firstNumber - secondNumber;
break;
case 'x': // Multiplication
secondNumber *= firstNumber;
break;
case '÷': // Division
try {
int divZeroTest = (int) firstNumber / (int) secondNumber;
secondNumber = firstNumber / secondNumber;
break;
} catch (ArithmeticException ex){
clearScreen = true;
return false;
}
case '%': // Percentage
secondNumber = (firstNumber / 100) * secondNumber;
break;
case '^': // Exponential power
secondNumber = Math.pow(firstNumber, secondNumber);
break;
case '√': // Square root
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.sqrt(secondNumber);
break;
case '&': // Exponential root
secondNumber = Math.pow(secondNumber, (1 / firstNumber));
break;
case 'S':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.sin(Math.toRadians(secondNumber));
break;
case 'C':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.cos(Math.toRadians(secondNumber));
break;
case 'T':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.tan(Math.toRadians(secondNumber));
break;
case 's':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.toDegrees(Math.asin(secondNumber));
break;
case 'c':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.toDegrees(Math.acos(secondNumber));
break;
case 't':
if (firstNumber == 0) {
firstNumber = 1;
}
secondNumber = firstNumber * Math.toDegrees(Math.atan(secondNumber));
break;
}
return true;
}
// MAIN CONSTRUCT
public CalcGUI() {
initGUI();
calcPanel.setLayout(new GridBagLayout());
// Add display box
gbcCalcPanel.gridx = 0;
gbcCalcPanel.gridy = 0;
gbcCalcPanel.fill = GridBagConstraints.HORIZONTAL;
gbcCalcPanel.gridwidth = 1;
calcPanel.add(upperDisplay = buildDisplay(), gbcCalcPanel);
// // Add second display box
// gbcCalcPanel.gridx = 0;
// gbcCalcPanel.gridy = 1;
// gbcCalcPanel.fill = GridBagConstraints.HORIZONTAL;
// gbcCalcPanel.gridwidth = 1;
// calcPanel.add(lowerDisplay = buildDisplay(), gbcCalcPanel);
// Add advanced calculator buttons
gbcCalcPanel.gridx = 0;
gbcCalcPanel.gridy = 2;
gbcCalcPanel.weighty = 1;
gbcCalcPanel.fill = GridBagConstraints.BOTH;
calcPanel.add(buildAdvancedButtonPanel(), gbcCalcPanel);
// Add calculator buttons
gbcCalcPanel.gridx = 0;
gbcCalcPanel.gridy = 3;
gbcCalcPanel.weighty = 1;
gbcCalcPanel.fill = GridBagConstraints.BOTH;
calcPanel.add(buildButtonPanel(), gbcCalcPanel);
setContentPane(calcPanel);
pack();
}
// DISPLAY BOX
private JTextField buildDisplay() {
JTextField t = new JTextField("", 16);
t.setHorizontalAlignment(SwingConstants.RIGHT);
t.setBackground(Color.DARK_GRAY);
t.setForeground(Color.GREEN);
t.setText("0");
t.setCaretPosition(1);
InputStream fontStream = ClassLoader.getSystemClassLoader().getResourceAsStream("DS-DIGII.TTF");
try {
Font calcDisplayFont = Font.createFont(Font.TRUETYPE_FONT, fontStream).deriveFont(60f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(calcDisplayFont);
t.setFont(calcDisplayFont);
} catch (IOException | FontFormatException ex) {
System.out.println(ex.getMessage());
Font calcDisplayFont = new Font("Lucida Console", Font.BOLD, 40);
t.setFont(calcDisplayFont);
}
return t;
}
// MAIN BUTTON PANEL
private JPanel buildButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBackground(Color.gray);
String[][] buttonText = {{"MC", "MR", "M-", "M+", "÷"},
{"+/-", "7", "8", "9", "x"},
{"%", "4", "5", "6", "-"},
{"√", "1", "2", "3", "+"},
{"CE", "0", ".", "=", "+"}};
int maxWidth = buttonText[0].length;
int maxHeight = buttonText.length;
JButton[][] calcButton = new JButton[maxHeight][maxWidth];
// cycle through button array and build
for (int yPos = 0; yPos < maxHeight; yPos++) {
for (int xPos = 0; xPos < maxWidth; xPos++) {
// build button panel, skipping button for extended '+' button
if (!(yPos == 4 && xPos == 4)) {
calcButton[yPos][xPos] = new JButton(buttonText[yPos][xPos]);
calcButton[yPos][xPos].setFont(calcButton[yPos][xPos].getFont().deriveFont(30f));
calcButton[yPos][xPos].setBackground(Color.black);
calcButton[yPos][xPos].addActionListener(this);
gbcButtonPanel.gridx = xPos;
gbcButtonPanel.gridy = yPos;
gbcButtonPanel.gridwidth = 1;
gbcButtonPanel.weightx = 1;
gbcButtonPanel.weighty = 1;
Insets buttonSpacing = new Insets(2,2,2,2);
gbcButtonPanel.insets = buttonSpacing;
// if the button being added is '+' extended it vertically
if (yPos == 3 && xPos == 4) {
gbcButtonPanel.gridheight = 2;
gbcButtonPanel.fill = GridBagConstraints.BOTH;
} else {
gbcButtonPanel.gridheight = 1;
gbcButtonPanel.fill = GridBagConstraints.BOTH;
}
panel.add(calcButton[yPos][xPos], gbcButtonPanel);
}
}
}
return panel;
}
// ADDITIONAL BUTTON PANEL
private JPanel buildAdvancedButtonPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setBackground(Color.darkGray);
String[][] buttonText = {{"<-", "xⁿ", "sin", "cos", "tan"},
{"π", "ⁿ√", "sin‾¹", "cos‾¹", "tan‾¹"}};
int maxWidth = buttonText[0].length;
int maxHeight = buttonText.length;
JButton[][] calcButton = new JButton[maxHeight][maxWidth];
// cycle through button array and build
for (int yPos = 0; yPos < maxHeight; yPos++) {
for (int xPos = 0; xPos < maxWidth; xPos++) {
calcButton[yPos][xPos] = new JButton(buttonText[yPos][xPos]);
calcButton[yPos][xPos].setFont(calcButton[yPos][xPos].getFont().deriveFont(30f));
calcButton[yPos][xPos].addActionListener(this);
gbcButtonPanel.gridx = xPos;
gbcButtonPanel.gridy = yPos;
gbcButtonPanel.gridwidth = 1;
gbcButtonPanel.weightx = 1;
gbcButtonPanel.weighty = 1;
gbcButtonPanel.gridheight = 1;
Insets buttonSpacing = new Insets(2,2,2,2);
gbcButtonPanel.insets = buttonSpacing;
gbcButtonPanel.fill = GridBagConstraints.BOTH;
panel.add(calcButton[yPos][xPos], gbcButtonPanel);
}
}
return panel;
}
// INITIALIZE GUI LOOK AND FEEL
private void initGUI() {
try {
// sets the look and feel to that of the OS if possible
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ex) {
// tell us a story
System.out.printf("Unable to load GUI.%n%s%n", ex.getMessage());
}
// set some window and frame options
setTitle(PROJ_TITLE);
setResizable(false);
setLocation(PROJ_WINDOW_LOCATION[0], PROJ_WINDOW_LOCATION[1]);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
// TEST IF REQUEST IS A NUMBER
private boolean digitTest(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException ex) {
return false;
}
}
// UPDATE DISPLAY
private void updateDisplay(String displayDigits) {
String displayString = upperDisplay.getText();
// Does screen need cleared before moving forward?
if (clearScreen) {
displayString = "0";
upperDisplay.setText(displayString);
clearScreen = false;
}
// Decimal handler
if (displayDigits.equals(".")){
if (!displayString.contains(displayDigits)) {
if (displayString.equals("0")) {
displayString = String.format("0%s", displayDigits);
} else {
displayString = String.format("%s", displayString + displayDigits);
}
}
} else { // No decimal
if (displayString.equals("0")) {
displayString = String.format("%s", displayDigits);
} else {
displayString = String.format(displayString + displayDigits);
}
}
// Check for DIV/0 and format string for display length
try {
// Check length and truncate
if (Double.parseDouble(displayString) < 0 && displayString.length() > 16) {
displayString = displayString.substring(0,16);
} else if (Double.parseDouble(displayString) > 0 && displayString.length() > 15) {
displayString = displayString.substring(0,15);
} else if (Double.isNaN(Double.parseDouble(displayString))) {
displayString = String.format("%-16s", "Domain Error");
reset();
}
} catch (NumberFormatException ex) {
displayString = String.format("%-17s", displayDigits);
}
upperDisplay.setText(displayString);
}
// DELETE LAST CHARACTER
private void deletePressed(){
int l = upperDisplay.getText().length();
int n = upperDisplay.getText().length() - 1;
if (l > 1) {
StringBuilder backSpace = new StringBuilder(upperDisplay.getText());
upperDisplay.setText(backSpace.deleteCharAt(n).toString());
} else {
upperDisplay.setText("0");
}
}
// CLEAR VARIABLES AND RESET
private void reset() {
firstNumber = 0;
secondNumber = 0;
operation = ' ';
clearScreen = true;
}
}