Last active
September 25, 2021 20:19
-
-
Save shiracamus/79cfaf88e9fddcc0d0dd115862410362 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//package myProgram; | |
import java.awt.BorderLayout; | |
import java.awt.GridLayout; | |
import java.awt.event.ActionEvent; | |
import java.math.BigDecimal; | |
import java.math.MathContext; | |
import java.math.RoundingMode; | |
import java.text.DecimalFormat; | |
import javax.swing.JComponent; | |
import javax.swing.JButton; | |
import javax.swing.JFrame; | |
import javax.swing.JPanel; | |
import javax.swing.JTextField; | |
import javax.swing.WindowConstants; | |
public class Calculator extends JFrame { | |
public static void main(String[] args) { | |
Calculator calculator = new Calculator("my電卓"); | |
calculator.setBounds(100, 100, 400, 250); | |
calculator.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); | |
calculator.setVisible(true); | |
} | |
// 数字入力や計算結果はentryに代入 | |
BigDecimal entry = BigDecimal.ZERO; | |
// "1+2=" 等の二項演算は operand=1 operator="+" entry=2 にして calculate() | |
BigDecimal operand = BigDecimal.ZERO; | |
final BinaryOperator NOP = () -> {}; | |
BinaryOperator operator = NOP; | |
String point = ""; // 浮動小数点入力なら"."、数値入力 | |
boolean enteringNumber = false; // "1+2√34" を "1+34" にするため | |
boolean replaceableOperator = false; // "1+-/*2" を "1*2" にするため | |
final DecimalFormat DISPLAY_FORMAT = new DecimalFormat("0.#########"); | |
JTextField display = new JTextField("0", 16); | |
NumberButton bt0 = new NumberButton("0"); | |
NumberButton bt1 = new NumberButton("1"); | |
NumberButton bt2 = new NumberButton("2"); | |
NumberButton bt3 = new NumberButton("3"); | |
NumberButton bt4 = new NumberButton("4"); | |
NumberButton bt5 = new NumberButton("5"); | |
NumberButton bt6 = new NumberButton("6"); | |
NumberButton bt7 = new NumberButton("7"); | |
NumberButton bt8 = new NumberButton("8"); | |
NumberButton bt9 = new NumberButton("9"); | |
BinaryButton btAdd = new BinaryButton("+", () -> { | |
setEntry(operand.add(entry)); | |
}); | |
BinaryButton btMultply = new BinaryButton("×", () -> { | |
setEntry(operand.multiply(entry)); | |
}); | |
BinaryButton btSubtract = new BinaryButton("-", () -> { | |
setEntry(operand.subtract(entry)); | |
}); | |
BinaryButton btDivide = new BinaryButton("÷", () -> { | |
if (entry.equals(BigDecimal.ZERO)) { | |
setEntry(BigDecimal.ZERO); //0除算時 | |
} else { | |
setEntry(operand.divide(entry, 9, RoundingMode.HALF_EVEN)); | |
} | |
}); | |
UnaryButton btPoint = new UnaryButton(".", () -> { | |
if (!enteringNumber) { | |
setEntry(BigDecimal.ZERO); | |
enteringNumber = true; | |
} | |
point = "."; | |
}); | |
UnaryButton btClear = new UnaryButton("C", () -> { | |
operand = BigDecimal.ZERO; | |
operator = NOP; | |
setEntry(BigDecimal.ZERO); | |
}); | |
UnaryButton btNegative = new UnaryButton("+/-", () -> { | |
setEntry(entry.multiply(new BigDecimal("-1"))); | |
}); | |
UnaryButton btSqrt = new UnaryButton("√", () -> { | |
try { | |
setEntry(entry.sqrt(new MathContext(9))); | |
} catch (ArithmeticException e) { | |
setEntry(BigDecimal.ZERO); // 負数時 | |
} | |
}); | |
UnaryButton btEqual = new UnaryButton("=", () -> { | |
calculate(); | |
}); | |
Calculator(String title) { | |
super(title); | |
buildComponents(); | |
} | |
void buildComponents() { | |
getContentPane().add(buildDisplay(), BorderLayout.NORTH); | |
getContentPane().add(buildButtons(), BorderLayout.CENTER); | |
} | |
JComponent buildDisplay() { | |
JPanel p = new JPanel(); | |
display.setHorizontalAlignment(JTextField.RIGHT); | |
display.setEditable(false); | |
p.add(display); | |
return p; | |
} | |
JComponent buildButtons() { | |
JPanel p = new JPanel(); | |
p.add(buildNumbers(), BorderLayout.CENTER); | |
p.add(buildFunctions(), BorderLayout.EAST); | |
return p; | |
} | |
JComponent buildNumbers() { | |
JPanel p = new JPanel(); | |
p.setLayout(new GridLayout(5, 3)); | |
p.add(btClear); p.add(btNegative); p.add(btSqrt); | |
p.add(bt7); p.add(bt8); p.add(bt9); | |
p.add(bt4); p.add(bt5); p.add(bt6); | |
p.add(bt1); p.add(bt2); p.add(bt3); | |
p.add(bt0); p.add(btPoint); | |
return p; | |
} | |
JComponent buildFunctions() { | |
JPanel p = new JPanel(); | |
p.setLayout(new GridLayout(5, 1)); | |
p.add(btDivide); | |
p.add(btMultply); | |
p.add(btSubtract); | |
p.add(btAdd); | |
p.add(btEqual); | |
return p; | |
} | |
void setEntry(BigDecimal value) { | |
entry = value; | |
display.setText(DISPLAY_FORMAT.format(entry)); | |
enteringNumber = false; | |
replaceableOperator = false; | |
} | |
void calculate() { | |
operator.calculate(); | |
operator = NOP; | |
enteringNumber = false; | |
replaceableOperator = false; | |
} | |
interface UnaryOperator { | |
void operate(); | |
} | |
interface BinaryOperator { | |
void calculate(); | |
} | |
class NumberButton extends JButton { | |
public NumberButton(final String number) { | |
super(number); | |
addActionListener((ActionEvent event) -> { | |
if (!enteringNumber) { | |
setEntry(BigDecimal.ZERO); | |
} | |
try { | |
setEntry(new BigDecimal(entry + point + number)); | |
} catch (NumberFormatException e) { | |
// 小数点が複数回入力された場合例外発生、無視する | |
} | |
point = ""; | |
enteringNumber = true; | |
replaceableOperator = false; | |
}); | |
} | |
} | |
class UnaryButton extends JButton { | |
UnaryButton(String label, final UnaryOperator unary) { | |
super(label); | |
addActionListener((ActionEvent event) -> { | |
unary.operate(); | |
}); | |
} | |
} | |
class BinaryButton extends JButton { | |
BinaryButton(String label, final BinaryOperator binary) { | |
super(label); | |
addActionListener((ActionEvent event) -> { | |
if (replaceableOperator) { | |
operator = binary; | |
return; | |
} | |
calculate(); | |
operand = entry; | |
operator = binary; | |
enteringNumber = false; | |
replaceableOperator = true; | |
}); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment