GUI 计算器出现奇怪的 Swing Java 错误?
Weird Swing Java Error in GUI Calculator?
我对 java 有点陌生,尤其是 swing 界面。我试图让它在显示两个数字的结果后输入一个数字,它只会清除它并用你按下的下一个数字替换它。例如,如果您添加 1 + 2 然后它显示 3,如果您按下数字 4,它将清除数字 3 并将其替换为 4。
下一个紧迫的问题是当我使用加法开关将两个数字相加时,它工作正常,除了它会显示第二个数字以及两个相加数字的结果。因此,例如,如果您添加 1 + 2,它将显示“23”,其中二是总和中的最后一个数字,而数字三是总和的结果。有帮助吗?
package javacalc;
import com.sun.source.tree.BreakTree;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
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 int operation = 0;
private boolean clearScreen = false;
private double firstNumber = 0;
private double secondNumber = 0;
DecimalFormat df = new DecimalFormat("0.##############");
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case ".": // decimal
updateDisplay(command);
break;
case "=": // equal
if (!upperDisplay.getText().equals("0")) {
secondNumber = Double.parseDouble(upperDisplay.getText());
switch (operation) {
case 2: // addition
updateDisplay(String.valueOf(df.format(firstNumber + secondNumber)));
break;
case 3: // subtraction
upperDisplay.setText(String.valueOf(df.format(firstNumber - secondNumber)));
break;
case 4: // multiplication
upperDisplay.setText(String.valueOf(df.format(firstNumber * secondNumber)));
break;
case 5: // division
upperDisplay.setText(String.valueOf(df.format(firstNumber / secondNumber)));
break;
case 6: // percent ( firstNumber % secondNumber = firstNumber% of secondNumber )
upperDisplay.setText(String.valueOf(df.format(((firstNumber / 100) * secondNumber))));
break;
case 7:
if (firstNumber == 0) { firstNumber = 1; }
upperDisplay.setText(String.valueOf(df.format(firstNumber * Math.sqrt(secondNumber))));
break;
case 8:
// upperDisplay.setText(String.valueOf(df.format()));
break;
case 9:
// upperDisplay.setText(String.valueOf(df.format()));
break;
}
}
break;
case "+": // add
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 2;
clearScreen = true;
break;
case "-": // subtract
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 3;
clearScreen = true;
break;
case "x": // multiply
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 4;
clearScreen = true;
break;
case "÷": // divide
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 5;
clearScreen = true;
break;
case "%": // percent
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 6;
clearScreen = true;
break;
// FIXME - +/- should not leave only '-' char when delete is pressed on last digit
// FIXME - if there is only one digit and it is not 0, and the - is active
// FIXME - it should not remove the last character and only leave -
// FIXME - it should change last remaining character to 0 and unalive the -
case "+/-": // negate
upperDisplay.setText(upperDisplay.getText().equals("0")||
(upperDisplay.getText().length() == 1 && upperDisplay.getText().equals("0"))?
"0":String.valueOf(df.format(Double.parseDouble(upperDisplay.getText()) * -1)));
break;
case "√": // square root
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 7;
clearScreen = true;
break;
case "xⁿ": // exponent
break;
case "ⁿ√": // exponent root
break;
case "π": // pi
break;
case "sin": // sine
break;
case "cos": // cosine
break;
case "tan": // tangent
break;
case "sin‾¹": // arcsine
break;
case "cos‾¹": // arccosine
break;
case "tan‾¹": // arctan
break;
case "<-": // backspace
deletePressed();
break;
case "CE": // clear
firstNumber = 0;
secondNumber = 0;
operation = 0;
clearScreen = false;
upperDisplay.setText("0");
// lowerDisplay.setText("0");
break;
case "M+": // mem+
break;
case "M-": // mem-
break;
case "MC": // mem clear
break;
default:
break;
}
}
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();
}
// BUILD 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);
try {
Font calcDisplayFont = Font.createFont(Font.TRUETYPE_FONT, new File("src\font\DS-DIGII.TTF")).deriveFont(60f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(calcDisplayFont);
t.setFont(calcDisplayFont);
} catch (IOException | FontFormatException e) {
System.out.println(e.getMessage());
Font calcDisplayFont = new Font("Lucida Console", Font.BOLD, 40);
t.setFont(calcDisplayFont);
}
return t;
}
// BUILD 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);
// test if button pressed is number or operation
// if number, send to display
if (calcButtonTest(buttonText[yPos][xPos])) {
String calcValue = calcButton[yPos][xPos].getText();
calcButton[yPos][xPos].addActionListener(e -> updateDisplay(calcValue));
} else {
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;
}
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 e) {
// tell us a story
System.out.printf("Unable to load GUI.%n%s%n", e.getMessage());
}
// set some window and frame options
setTitle(PROJ_TITLE);
// setPreferredSize(new Dimension(PROJ_WINDOW_SIZE[0], PROJ_WINDOW_SIZE[1]));
setResizable(false);
setLocation(PROJ_WINDOW_LOCATION[0], PROJ_WINDOW_LOCATION[1]);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private boolean calcButtonTest(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
// UPDATE DISPLAY
private void updateDisplay(String s) {
StringBuilder displayString = new StringBuilder();
System.out.println(s);
if (clearScreen) {
upperDisplay.setText("");
clearScreen = false;
}
if (Double.parseDouble(s) < 0) {
System.out.println("neg");
}
if (upperDisplay.getText().length() + 1 <= 15) {
// DECIMAL HANDLER
if (s.equals(".")){
if (!upperDisplay.getText().contains(s)) {
if (upperDisplay.getText().equals("0")) {
upperDisplay.setText(String.format("0%s", s));
} else {
upperDisplay.setText(String.format("%s", upperDisplay.getText() + s));
}
}
} else {
if (upperDisplay.getText().equals("0")) {
upperDisplay.setText(String.format("%s", s));
} else {
upperDisplay.setText(String.format("%s", upperDisplay.getText() + s));
}
}
}
}
// 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");
}
}
}
尽管看起来一切都不正常,但其他所有基本运算符都可以正常工作。乘法、除法和减法都可以正常工作。
特别针对您的问题,+
operation
的行为与其他行为不同,解释为您的 switch
陈述中存在差异。
对 operation
3 及更高版本(在此代码段中实现的那些)的调用都直接调用 upperDisplay.setText(...)
并导致上面的显示输出被覆盖。您的 +
操作代码调用了您的方法 updateDisplay(...)
,它具有额外的逻辑,不会直接替换上面显示的文本。
如果你更换
case 2: // addition
updateDisplay(String.valueOf(df.format(firstNumber + secondNumber)));
break;
与
case 2: // addition
upperDisplay.setText(String.valueOf(df.format(firstNumber + secondNumber)));
break;
那么 +
的行为应该与其他行为一致。
但是,当您开始输入另一个计算时(例如在 1
+
2
输出 3
之后,此实现似乎也不会清除您的显示,按 4
将导致您的显示呈现 34
并且 34
最终被解析为您的下一个“第一个”数字而不是 4
).
您可能需要考虑在 switch 语句的末尾附加以下内容:
if (!upperDisplay.getText().equals("0")) {
secondNumber = Double.parseDouble(upperDisplay.getText());
switch(operation) {
...
}
clearScreen = true; // <- add this
}
以便您可以无缝过渡到进入下一个计算。
我对 java 有点陌生,尤其是 swing 界面。我试图让它在显示两个数字的结果后输入一个数字,它只会清除它并用你按下的下一个数字替换它。例如,如果您添加 1 + 2 然后它显示 3,如果您按下数字 4,它将清除数字 3 并将其替换为 4。
下一个紧迫的问题是当我使用加法开关将两个数字相加时,它工作正常,除了它会显示第二个数字以及两个相加数字的结果。因此,例如,如果您添加 1 + 2,它将显示“23”,其中二是总和中的最后一个数字,而数字三是总和的结果。有帮助吗?
package javacalc;
import com.sun.source.tree.BreakTree;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
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 int operation = 0;
private boolean clearScreen = false;
private double firstNumber = 0;
private double secondNumber = 0;
DecimalFormat df = new DecimalFormat("0.##############");
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
switch (command) {
case ".": // decimal
updateDisplay(command);
break;
case "=": // equal
if (!upperDisplay.getText().equals("0")) {
secondNumber = Double.parseDouble(upperDisplay.getText());
switch (operation) {
case 2: // addition
updateDisplay(String.valueOf(df.format(firstNumber + secondNumber)));
break;
case 3: // subtraction
upperDisplay.setText(String.valueOf(df.format(firstNumber - secondNumber)));
break;
case 4: // multiplication
upperDisplay.setText(String.valueOf(df.format(firstNumber * secondNumber)));
break;
case 5: // division
upperDisplay.setText(String.valueOf(df.format(firstNumber / secondNumber)));
break;
case 6: // percent ( firstNumber % secondNumber = firstNumber% of secondNumber )
upperDisplay.setText(String.valueOf(df.format(((firstNumber / 100) * secondNumber))));
break;
case 7:
if (firstNumber == 0) { firstNumber = 1; }
upperDisplay.setText(String.valueOf(df.format(firstNumber * Math.sqrt(secondNumber))));
break;
case 8:
// upperDisplay.setText(String.valueOf(df.format()));
break;
case 9:
// upperDisplay.setText(String.valueOf(df.format()));
break;
}
}
break;
case "+": // add
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 2;
clearScreen = true;
break;
case "-": // subtract
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 3;
clearScreen = true;
break;
case "x": // multiply
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 4;
clearScreen = true;
break;
case "÷": // divide
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 5;
clearScreen = true;
break;
case "%": // percent
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 6;
clearScreen = true;
break;
// FIXME - +/- should not leave only '-' char when delete is pressed on last digit
// FIXME - if there is only one digit and it is not 0, and the - is active
// FIXME - it should not remove the last character and only leave -
// FIXME - it should change last remaining character to 0 and unalive the -
case "+/-": // negate
upperDisplay.setText(upperDisplay.getText().equals("0")||
(upperDisplay.getText().length() == 1 && upperDisplay.getText().equals("0"))?
"0":String.valueOf(df.format(Double.parseDouble(upperDisplay.getText()) * -1)));
break;
case "√": // square root
firstNumber = Double.parseDouble(upperDisplay.getText());
operation = 7;
clearScreen = true;
break;
case "xⁿ": // exponent
break;
case "ⁿ√": // exponent root
break;
case "π": // pi
break;
case "sin": // sine
break;
case "cos": // cosine
break;
case "tan": // tangent
break;
case "sin‾¹": // arcsine
break;
case "cos‾¹": // arccosine
break;
case "tan‾¹": // arctan
break;
case "<-": // backspace
deletePressed();
break;
case "CE": // clear
firstNumber = 0;
secondNumber = 0;
operation = 0;
clearScreen = false;
upperDisplay.setText("0");
// lowerDisplay.setText("0");
break;
case "M+": // mem+
break;
case "M-": // mem-
break;
case "MC": // mem clear
break;
default:
break;
}
}
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();
}
// BUILD 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);
try {
Font calcDisplayFont = Font.createFont(Font.TRUETYPE_FONT, new File("src\font\DS-DIGII.TTF")).deriveFont(60f);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(calcDisplayFont);
t.setFont(calcDisplayFont);
} catch (IOException | FontFormatException e) {
System.out.println(e.getMessage());
Font calcDisplayFont = new Font("Lucida Console", Font.BOLD, 40);
t.setFont(calcDisplayFont);
}
return t;
}
// BUILD 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);
// test if button pressed is number or operation
// if number, send to display
if (calcButtonTest(buttonText[yPos][xPos])) {
String calcValue = calcButton[yPos][xPos].getText();
calcButton[yPos][xPos].addActionListener(e -> updateDisplay(calcValue));
} else {
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;
}
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 e) {
// tell us a story
System.out.printf("Unable to load GUI.%n%s%n", e.getMessage());
}
// set some window and frame options
setTitle(PROJ_TITLE);
// setPreferredSize(new Dimension(PROJ_WINDOW_SIZE[0], PROJ_WINDOW_SIZE[1]));
setResizable(false);
setLocation(PROJ_WINDOW_LOCATION[0], PROJ_WINDOW_LOCATION[1]);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private boolean calcButtonTest(String s) {
try {
Integer.parseInt(s);
return true;
} catch (NumberFormatException e) {
return false;
}
}
// UPDATE DISPLAY
private void updateDisplay(String s) {
StringBuilder displayString = new StringBuilder();
System.out.println(s);
if (clearScreen) {
upperDisplay.setText("");
clearScreen = false;
}
if (Double.parseDouble(s) < 0) {
System.out.println("neg");
}
if (upperDisplay.getText().length() + 1 <= 15) {
// DECIMAL HANDLER
if (s.equals(".")){
if (!upperDisplay.getText().contains(s)) {
if (upperDisplay.getText().equals("0")) {
upperDisplay.setText(String.format("0%s", s));
} else {
upperDisplay.setText(String.format("%s", upperDisplay.getText() + s));
}
}
} else {
if (upperDisplay.getText().equals("0")) {
upperDisplay.setText(String.format("%s", s));
} else {
upperDisplay.setText(String.format("%s", upperDisplay.getText() + s));
}
}
}
}
// 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");
}
}
}
尽管看起来一切都不正常,但其他所有基本运算符都可以正常工作。乘法、除法和减法都可以正常工作。
特别针对您的问题,+
operation
的行为与其他行为不同,解释为您的 switch
陈述中存在差异。
对 operation
3 及更高版本(在此代码段中实现的那些)的调用都直接调用 upperDisplay.setText(...)
并导致上面的显示输出被覆盖。您的 +
操作代码调用了您的方法 updateDisplay(...)
,它具有额外的逻辑,不会直接替换上面显示的文本。
如果你更换
case 2: // addition
updateDisplay(String.valueOf(df.format(firstNumber + secondNumber)));
break;
与
case 2: // addition
upperDisplay.setText(String.valueOf(df.format(firstNumber + secondNumber)));
break;
那么 +
的行为应该与其他行为一致。
但是,当您开始输入另一个计算时(例如在 1
+
2
输出 3
之后,此实现似乎也不会清除您的显示,按 4
将导致您的显示呈现 34
并且 34
最终被解析为您的下一个“第一个”数字而不是 4
).
您可能需要考虑在 switch 语句的末尾附加以下内容:
if (!upperDisplay.getText().equals("0")) {
secondNumber = Double.parseDouble(upperDisplay.getText());
switch(operation) {
...
}
clearScreen = true; // <- add this
}
以便您可以无缝过渡到进入下一个计算。