tags:

views:

83

answers:

2

I have hit a brick wall whilst attempting to create a two-class Java calculator. I have the code for an interface which works and displays ok but creating a separate class 'CalcEngine' to do the actual calculations has proven to be beyond me.

I'd appreciate it if someone could kick start things for me and create a class calcEngine which works with the interface class and allows input when from single button i.e. if one is pressed on the calc then 1 displays onscreen.

Please note I'm not asking someone to do the whole thing for me as I want to learn and I'm confident I can do the rest including addition subtraction etc. Once I get over the obstacle of getting the two classes to communicate. Any and all assistance would be very much appreciated.

Please see the calcInterface class code below:

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

/**
*A Class that operates as the framework for a calculator. 
*No calculations are performed in this section
*/
public class CalcFrame
implements ActionListener
{
    private CalcEngine calc;

    private JFrame frame;
    private JTextField display;
    private JLabel status;

    /**
     * Constructor for objects of class GridLayoutExample
     */
    public CalcFrame()
    {
        makeFrame();
        //calc = engine;
    }

    /**
     * This allows you to quit the calculator.
     */
    // Alows the class to quit.
    private void quit()
    {
        System.exit(0);
    }

    // Calls the dialog frame with the information about the project.
    private void showAbout()
    {
        JOptionPane.showMessageDialog(frame, 
                    "Group Project",
                    "About Calculator Group Project", 
                    JOptionPane.INFORMATION_MESSAGE);
    }


    private void makeFrame()
    {
        frame = new JFrame("Group Project Calculator");
        makeMenuBar(frame);

        JPanel contentPane = (JPanel)frame.getContentPane();
        contentPane.setLayout(new BorderLayout(8, 8));
        contentPane.setBorder(new EmptyBorder( 10, 10, 10, 10));

        /**
     * Insert a text field
     */
        display = new JTextField();
        contentPane.add(display, BorderLayout.NORTH);

        //Container contentPane = frame.getContentPane();
        contentPane.setLayout(new GridLayout(4, 4));
        JPanel buttonPanel = new JPanel(new GridLayout(4, 4));
        contentPane.add(new JButton("1"));
        contentPane.add(new JButton("2"));
        contentPane.add(new JButton("3"));
        contentPane.add(new JButton("4"));
        contentPane.add(new JButton("5"));
        contentPane.add(new JButton("6"));
        contentPane.add(new JButton("7"));
        contentPane.add(new JButton("8"));
        contentPane.add(new JButton("9"));
        contentPane.add(new JButton("0"));
        contentPane.add(new JButton("+"));
        contentPane.add(new JButton("-"));
        contentPane.add(new JButton("/"));
        contentPane.add(new JButton("*"));
        contentPane.add(new JButton("="));
        contentPane.add(new JButton("C"));

        contentPane.add(buttonPanel, BorderLayout.CENTER);

        //status = new JLabel(calc.getAuthor());
        //contentPane.add(status, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Create the main frame's menu bar.
     * The frame that the menu bar should be added to.
     */
    private void makeMenuBar(JFrame frame)
    {
        final int SHORTCUT_MASK =
            Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

        JMenuBar menubar = new JMenuBar();
        frame.setJMenuBar(menubar);

        JMenu menu;
        JMenuItem item;

        // create the File menu
        menu = new JMenu("File");
        menubar.add(menu);

        // create the Quit menu with a shortcut "Q" key.
         item = new JMenuItem("Quit");
            item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { quit(); }
                           });
        menu.add(item);

        // Adds an about menu.
        menu = new JMenu("About");
        menubar.add(menu);

        // Displays 
        item = new JMenuItem("Calculator Project");
            item.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) { showAbout(); }
                           });
        menu.add(item);
    }


 /**
     * An interface action has been performed.
     * Find out what it was and handle it.
     * @param event The event that has occured.
     */
    public void actionPerformed(ActionEvent event)
    {
        String command = event.getActionCommand();

        if(command.equals("0") ||
           command.equals("1") ||
           command.equals("2") ||
           command.equals("3") ||
           command.equals("4") ||
           command.equals("5") ||
           command.equals("6") ||
           command.equals("7") ||
           command.equals("8") ||
           command.equals("9")) {
            int number = Integer.parseInt(command);
            calc.numberPressed(number);
        }
        else if(command.equals("+")) {
            calc.plus();
        }
        else if(command.equals("-")) {
            calc.minus();
        }
        else if(command.equals("=")) {
            calc.equals();
        }
        else if(command.equals("C")) {
            calc.clear();
        }
        else if(command.equals("?")) {

        }
        // else unknown command.

        redisplay();
    }

    /**
     * Update the interface display to show the current value of the 
     * calculator.
     */
    private void redisplay()
    {
        display.setText("" + calc.getDisplayValue());
    }

    /**
     * Toggle the info display in the calculator's status area between the
     * author and version information.
     */
}
+1  A: 

The trick to recognise that the calculator needs to have a "state". It is easier to visualize operations which require two operands and those which require a single operand (square-root for eg.). So add a nice state holder (instance variable) which holds the previous entry which is accessible to the actual calculation engine. Hope this is what your were asking for.

Explanation added

On each of the Jbutton's add a button listener. Have a instance variable such as double firstOp and another instance variable String operationType. On click event of numeric buttons, keep appending values to text area. On click of operand parse the string contained in textArea to firstOp. Double class has the methods to do this. Store the operand value in operationType field (PLUS, MINUS etc). if it is single operand operator. Call Calc Engine's method and return the value (set the value in text field). Else clear the text field and keep appending the values until '=' is triggered, in which case, using firstOp, operationType and current value in text field determine the method to be called on Calc Engine. Finally return the value.

questzen
hi, thanks for your response, i'm afraid i'm a beginner at this so you answer is a bit above my level, could you possibly suggest the code for the calcEngine class to get me started, for instance what do i need to enter to get it to recognise when 1 or any other button for that matter is pressed? thanks again.
tokee
+1  A: 

You could create a class CalcEngine and use calc = new CalcEngive() in the CalcFrame constructor.

The engine class could maintain 2 long attributes, the current value and the previous value and an enumated value to remember the operator chosen.

The numberPressed method multiplies the current value by 10 and adds the number. When you press an operator, copy the current value to the previous value (taking into account any remembered oparator present in the enumerator attribute.) The assignment operator copies the result of the operation back into the current value and the 'C' operator clears both current and previous value.

As you see, you can implement all functionality that is present in the UI frame method by method.

Hopefully this will help you get started. Once you do I'm sure it will all fall into place.

Update:

After staring at your empty CalcEngine class for a while (did you get the CalcFrame source as part of the assignment?) the next steps to take are:

  • add the attributes mentioned above
  • look at your CalcFrame source and identify calls to the engine; calc.xxxxx()
  • add the methods you found in the previous step and check dependencies by compiling
  • implement the methods
rsp
hi thanks for the input, in terms of the calc engine class, could you be a bit more specific please insofar as what needs to be added to it, currently i just have a blank class called calcEngine and i'm unsure what to add to it... any/all assistance would be much appreciated as i've tied myself up in notes with this! thanks in advance.
tokee