【问题标题】:Trouble determining how to make my calculator calculate properly无法确定如何让我的计算器正确计算
【发布时间】:2017-08-30 09:56:04
【问题描述】:

这可能是您第 n 次收到关于计算器的新手问题,但我就是想不通,已经研究了两到三天。目前我构建计算器的方式还不够,我知道我必须在按下“=”按钮时开始计算,但我根本不知道该怎么做。由于这个原因,我已经恢复到我原来的计算器代码,当我按下一个不起作用的操作按钮(如“+”)时它会计算,但我希望这能让我正确地建立它.代码如下:

package rekenmachine;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;

public class Rekenmachine extends JFrame
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame();
        frame.setSize(300,500);
        frame.setLocation(800,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Rekenmachine");
        RekenPaneel rekenpaneel = new RekenPaneel();
        frame.setContentPane(rekenpaneel);
        frame.setVisible(true);
    }

    private static int getal, totaalGetal;
    private boolean optellen, aftrekken, vermenigvuldigen, delen;

     public int Optellen(int getal)
    {
        reset();
        optellen = true;
        totaalGetal += getal;
        getal = 0;
        return totaalGetal;
    }
    public int Aftrekken(int getal)
    {
        reset();
        aftrekken = true;
        totaalGetal -= getal;
        getal = 0;
        return totaalGetal;
    }
    public int Delen(int getal)
    {
        reset();
        delen = true;
        totaalGetal /= getal;
        getal = 0;
        return totaalGetal;
    }
    public int Vermenigvuldigen(int getal)
    {
        reset();
        vermenigvuldigen = true;
        totaalGetal *= getal;
        getal = 0;
        return totaalGetal;
    }
    public int getGetal()
    {
        return getal;
    }
    public int getTotaalGetal()
    {
        return totaalGetal;
    }
    public void reset()
    {
        optellen = false;
        aftrekken = false;
        delen = false;
        vermenigvuldigen = false;

        getal = 0;
        totaalGetal = 0;
    }
}

class RekenPaneel extends JPanel
{
    JButton knop0, knop1, knop2, knop3, knop4, knop5, knop6, knop7, knop8, knop9,
            knopOptel, knopAftrek, knopVermenigvuldigen, knopDelen, knopUitkomst,
            knopWissen;
    JTextField invoerVak;
    JPanel textPaneel, knopPaneel, logoPaneel;
    Rekenmachine rekenmachine;

    public RekenPaneel()
    {
        rekenmachine = new Rekenmachine();

        setLayout(new BorderLayout());

        textPaneel = new JPanel();
        knopPaneel = new JPanel();
        logoPaneel = new JPanel();

        textPaneel.setLayout(new FlowLayout());
        knopPaneel.setLayout(new GridLayout(4,4));
        logoPaneel.setLayout(new FlowLayout());

        Border rand = BorderFactory.createEmptyBorder(10, 10, 10, 10);

        knop0 = new JButton("0");
        knop0.addActionListener(new knop0Handler());

        knop1 = new JButton("1");
        knop1.addActionListener(new knop1Handler());

        knop2 = new JButton("2");
        knop2.addActionListener(new knop2Handler());

        knop3 = new JButton("3");
        knop3.addActionListener(new knop3Handler());

        knop4 = new JButton("4");
        knop4.addActionListener(new knop4Handler());

        knop5 = new JButton("5");
        knop5.addActionListener(new knop5Handler());

        knop6 = new JButton("6");
        knop6.addActionListener(new knop6Handler());

        knop7 = new JButton("7");
        knop7.addActionListener(new knop7Handler());

        knop8 = new JButton("8");
        knop8.addActionListener(new knop8Handler());

        knop9 = new JButton("9");
        knop9.addActionListener(new knop9Handler());

        knopOptel = new JButton("+");
        knopOptel.addActionListener(new knopOptelHandler());

        knopAftrek = new JButton("-");
        knopAftrek.addActionListener(new knopAftrekHandler());

        knopVermenigvuldigen = new JButton("*");
        knopVermenigvuldigen.addActionListener(new knopVermenigvuldigenHandler());

        knopDelen = new JButton("/");
        knopDelen.addActionListener(new knopDelenHandler());

        knopUitkomst = new JButton("=");
        knopUitkomst.addActionListener(new knopUitkomstHandler());

        knopWissen = new JButton("C");
        knopWissen.addActionListener(new knopWissenHandler());

        invoerVak = new JTextField(25);
        invoerVak.setHorizontalAlignment(invoerVak.RIGHT);
        invoerVak.setEditable(false);
        invoerVak.setBackground(Color.WHITE);

        textPaneel.add(invoerVak);
        knopPaneel.add(knop7);
        knopPaneel.add(knop8);
        knopPaneel.add(knop9);
        knopPaneel.add(knopDelen);
        knopPaneel.add(knop4);
        knopPaneel.add(knop5);
        knopPaneel.add(knop6);
        knopPaneel.add(knopVermenigvuldigen);
        knopPaneel.add(knop1);
        knopPaneel.add(knop2);
        knopPaneel.add(knop3);
        knopPaneel.add(knopOptel);
        knopPaneel.add(knop0);
        knopPaneel.add(knopWissen);
        knopPaneel.add(knopUitkomst);
        knopPaneel.add(knopAftrek);

        add(textPaneel, BorderLayout.NORTH);
        add(knopPaneel, BorderLayout.CENTER);
        add(logoPaneel, BorderLayout.SOUTH);
    }
    class knop0Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "0");
        }
    }
    class knop1Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "1");
        }
    }
    class knop2Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "2");
        }
    }
    class knop3Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "3");
        }
    }
    class knop4Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "4");
        }
    }
    class knop5Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "5");
        }
    }
    class knop6Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "6");
        }
    }
    class knop7Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "7");
        }
    }
    class knop8Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "8");
        }
    }
    class knop9Handler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText(invoerVak.getText() + "9");
        }
    }
    class knopOptelHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Optellen(invoerGetal);
            invoerVak.setText("");

        }
    }
    class knopAftrekHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Aftrekken(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopVermenigvuldigenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Vermenigvuldigen(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopDelenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Delen(invoerGetal);
            invoerVak.setText("");
        }
    }
    class knopUitkomstHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            invoerVak.setText("" + rekenmachine.getTotaalGetal());
            rekenmachine.reset();
        }
    }
    class knopWissenHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            rekenmachine.reset();
            invoerVak.setText("");
        }
    }
}

它基本上看起来像一个计算器,所有按钮都可以工作,但它的计算方式很不一样,如果有的话。我想我需要做的是保存一个数字,当我按 + 时它应该添加下一个数字,如果我按 - 它应该减去下一个数字,如果我按 * 它应该乘以下一个数字,如果我按 /它应该除以下一个数字,然后当我按 = 时它应该显示结果,但我不知道该怎么做。

应该用数组列表来完成吗?如果是这样,我怎样才能正确保存结果?我的意思是,用两个数字使用它并不难,你只需保存两个数字并用它们做一些事情,然后显示结果,但一个人并不总是只使用两个数字。

为了更清楚地解释我遇到的问题:例如,当我输入“50”然后按“+”时,它应该将“50”转换为 getal = 50 并启动 Optellen 方法,然后 totaalGetal 应该变为 50 ,然后清空文本字段。如果我然后添加“3”,当我按“=”时它应该显示 53,但如果我幸运的话,它仍然显示 50。为了解决这个问题,我假设我必须在按下“=”时进行计算,但在完成之前我不知道如何保存/计算数字。

谁能告诉我在我掉头发之前该怎么做? :P

【问题讨论】:

  • 用英语编码是个好习惯:p 尤其是在需要帮助的情况下,并不是每个人都会说荷兰语^^“但它的计算方式却很遥远”这是什么意思?
  • 由于某些原因,我不得不用荷兰语编写代码。好吧,这意味着它永远不会做我想做的事。如上一段所述,例如,它应该得到 53 和 50 + 3,对吗?然而它仍然保持在 50 或 0,因为我觉得它在错误的地方计算,因此不会做任何事情或不会正确地做。 getal = number totaalGetal = totalNumber knop = button optellen = add aftrekken = subvermenigvuldigen = multiply delen = ehm... /
  • 您的reset() 呼叫有问题。您在奇怪的时间将 getaltotaalGetal 设置为 0。
  • 哦,废话!好吧,我忘了编辑那个,它过去只重置布尔值。虽然基本上是相同的东西,但它没有正确添加并且减法将数字变为负数,我相信乘法和除法(这是我之前正在寻找的词)甚至都不起作用。 reset() 最初位于正确的位置。换句话说,reset() 并没有更早地导致问题。我知道我忘了编辑一些东西 xD
  • 将 reset() 方法拆分为两个方法,将“将变量更改为 0”和“重置所有布尔值”部分分开。

标签: java swing jframe calculator


【解决方案1】:

当您点击+ 时,您正在调用:

    knopOptel.addActionListener((ActionEvent e) ->
    {
        String invoer = invoerVak.getText();
        int invoerGetal = Integer.parseInt(invoer);
        rekenmachine.addition(invoerGetal);
        invoerVak.setText("");
    });

但是当您点击+ 时,您还没有进行计算!你应该做的是:

  • 用户输入数字
  • 用户点击+(例如)
  • ActionListener 中,您读取屏幕上的数字,将其存储在getal 中,清除屏幕,并将布尔值optel 设置为true
  • 用户键入另一个数字
  • 用户点击相等
  • 在相等的Listener 中,您读取屏幕上的数字,并根据标志(示例中为optel)计算结果
  • 你显示结果

确实,当你按下相等时,计算就完成了。

一个小代码示例:

knopOptel.addActionListener((ActionEvent e) ->
{
    int invoerGetal = Integer.parseInt(invoerVak.getText()); // get the number
    calculate(invoerGetal); //sets totalNumber to what it should be by looking at the flags
    invoerVak.setText(totalNumber); // we write the temporary result
    additionFlag = true; // next number must be added
});

你的calculate 函数应该是这样的:

private void calculate(int aInvoerGetal) {
    if (addition)
        totalNumber += aInvoerGetal;
    else if (substract)
        totalNumber -= aInvoerGetal;
    else if (divide)
        totalNumber /= aInvoerGetal;
    else if (multiply)
        totalNumber *= aInvoerGetal;

    resetFlags();
}

更进一步:

现在,如果您想支持多个计算 (5+5+5+3),这很容易。当你点击+-*/时,你首先调用equalActionListener

这样,你得到这样的序列:

  1. 5, + // ==> 等于调用 ==> 5(因为标志都是假的)==> 标志 + 为真

  2. 10, + // ==> 等于调用 ==> 15,因为 5 在内存中并且 + 标志已打开。 + 标志熄灭,然后再次亮起(因为您再次按下 +

  3. 4, = // ==> 等于调用 ==> 19

【讨论】:

  • 这……很有意义!当我有时间再次编程时(可能明天),我一定会把你所说的融入我的代码中,并一遍又一遍地分析它,直到我完全理解为止。不过,它确实已经给了我一个“尤里卡”的时刻,哈哈。非常感谢!
  • @WesleyOrth 没问题,很高兴我能帮上忙。如果您希望我对此添加更多精度,请不要犹豫。如果您认为这回答了您的问题,您可以将其标记为已接受:D
  • 如何从 + 或其他调用 equalActionListener?另外,由于我对整个“课堂思考”的思维方式很陌生,所以我现在很困惑……就是这样,我明白了,但我不知道该怎么做……你能帮忙吗请问我吗?
  • 好吧,实际上您不必将其设为actionListener。将其设为全局函数,并在 plusListener 的开头调用它。
  • @WesleyOrth 事情是,请记住您的计算应该在处理到下一个之前完成。所以:5 + 5 -> 5 + (= 5) 5 + (= 10) 5 = 15
【解决方案2】:

在开发某些东西时,您必须首先考虑如何解决问题。通过设计解决方案从那里开始工作。如果您有一个可编程的解决方案,请实施它。 UI 可能会稍后出现。这是开发人员应该具备的核心技能。

1) 您想要一个支持 +、-、/ 和 * 的计算器。如果单击“=”,则应显示输出。

2) 与类一起思考。这个概念对你来说可能是新的,但你稍后会发现。您进行计算的主要课程是Rekenmachine。 (从设计的角度来看,它应该是一个独立的类,但现在这并不重要)。您需要将其与 UI 层分开。

您的类支持您使用 UI 实现的操作。那挺好的。但我也看到了不应该存在的东西

public int Vermenigvuldigen(int getal)
{
    reset(); // reset the calculator ?
    vermenigvuldigen = true; // purpose ?
    totaalGetal *= getal;
    getal = 0; // resetting argument getal ?
    return totaalGetal;
}

在这里,我不知道你为什么打电话给reset(),因为它的作用是

public void reset()
{
    optellen = false;
    aftrekken = false;
    delen = false;
    vermenigvuldigen = false;

    getal = 0;
    totaalGetal = 0;
}

阅读上述方法时,您会看到它重置了您尝试添加的值。当然,您的计算会出错,因为您正在擦除以前的数据......将所有内容重置为初始状态。我也不明白动作的“真”或“假”设置。也许是为了用户界面?这不是必需的。

简单点:

创建Rekenmachine时,将变量totaalGetal默认设置为0。该变量保存您迄今为止执行的计算的值。这就是开始。当您有添加时,请使用

public void add(int getal) {
  totaalGetal+= getal; // means totaalGetal = totaalGetal + getal.
}

在调用add() 之前,您必须将字符串解析为整数。这可以在按钮操作中完成:

class knop1Handler implements ActionListener
{
    public void actionPerformed(ActionEvent e)
    {
        // get input
        String input = invoerVak.getText();
        // convert
        int converted = convertToInt(input);
        // instruct myRekenmachine to add the value
        myRekenmachine.add(converted);
    }
}

重要提示...使用简洁的命名...“knop1handler”很难阅读。使用“addButtonHandler”表示该类处理添加按钮。 convertToInt 是一种读取字符串并返回整数的方法。您必须自己实施。 myRekenmachine 是您的 Rekenmachine 类的一个实例。

以上是补充。对其他操作数实现相同的操作。如果要调整 UI,请在处理程序中进行。

现在,当您按下 = 时,只需返回 totaalGetal 值。

PS:不确定,但请问您是否可以用英文写名字。我的母语是荷兰语,但在我的 CS 课程期间,我可以完全用英语编程。如果您的目标是从事 IT 行业,请尝试询问,因为英语是 IT 世界的主要语言。

【讨论】:

  • 感谢您的回答,但除非我做错了什么,否则如果您不计算它周围的所有绒毛,它实际上与我所做的没有什么不同。我实际上是这样开始的,但那时错误也开始出现......除了 convertToInt,由于某种奇怪的原因似乎无法识别,Alt + Enter 显示没有任何可行的方法。我使用 Netbeans。
  • " convertToInt 是一个读取字符串并返回整数的方法。你必须自己实现它 " (@987654334 @ 带有异常处理......)但是......刚刚意识到最好使用double(以支持小数和/的正确使用)。呵呵。
  • '很明显你是编程新手。在开发某些东西时,您必须首先考虑您想如何解决问题。通过设计解决方案从那里开始工作。如果您有一个可编程的解决方案,请实施它。' 您的确切意思是什么?请告诉我更多关于核心开发人员技能的信息吗?
【解决方案3】:

Wesley,在开始编码之前,您是否考虑过您希望计算器执行的操作?例如它会支持括号,sin/cos,内存吗?您是否考虑过这些函数在逻辑上如何工作,然后考虑如何在 Java 中实现它们?当您开始使用一种新语言时,如果只是为了帮助您理解您正在尝试做什么,那么一些流程图和一些伪代码可能会有很长的路要走。

顺便说一句,我知道从 GUI 代码开始并进入应用程序的逻辑很诱人,但通常最好从逻辑开始然后进入 GUI。您可以对输入的值进行硬编码,并查看功能是否按预期运行,然后使用从其他位置传入的值引入参数。

编辑

我想我知道为什么你的 + 键不起作用了。 reset() 方法在添加之前将 getal 和 totalGetal 设置为 0。 0 + 0 是 0。

knopOptel = new JButton("+");
        knopOptel.addActionListener(new knopOptelHandler()); 


 class knopOptelHandler implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            String invoer = invoerVak.getText();
            int invoerGetal = Integer.parseInt(invoer);
            rekenmachine.Optellen(invoerGetal);
            invoerVak.setText("");

        }
    }


     public int Optellen(int getal)
    {
        reset();

            public void reset()
            {
            optellen = false;
            aftrekken = false;
            delen = false;
            vermenigvuldigen = false;

            getal = 0;
            totaalGetal = 0;
            }

    optellen = true;
    totaalGetal += getal;
    getal = 0;
    return totaalGetal;
}

【讨论】:

  • 嗯...是的,我制作了其中一张 UML 图表。但是,当代码没有按照我的意愿执行时,我开始对其进行编辑,一路上它可能变得有点小混乱哈哈...哈哈。
  • @user8537453 虽然您的回答解决了该问题的一些问题,但它没有回答它,最好作为评论:)
  • 我的声望为 2,至少需要达到 50 才能添加评论。我有点不愿意将代码交给显然是家庭作业或自学课程的一部分。韦斯利最好找到解决方案,然后再回来解决他们遇到的任何新问题。
  • 感谢您的反馈。
  • 我同意,我不希望向我提供答案,只是一个新的观点或一个可以这么说的课程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多