0

I've recently been having problems modifying the size of the buttons on my swing calculator. If you run it, you'll see a calculator that almost works as fine as a regular windows calculator. But I'm trying to make it look exactly like a regular windows calculator. I've put down the code, and I have a few questions.

  1. If you press equals twice, you'll find that the number on the text will be set to zero. Could someone give me a hint to fix that?
  2. If you press two consecutive functions (exe. add then multiply), you'll see that it usually does the first function. It should do the second function pressed. Again, could someone give me a hint to fix that?
  3. Ggraphics: How do you resize the buttons? I tried calling buttons.resize(), and it should have worked as it was in the java API, but for some reason it has no effect.
  4. How do you set the text on the buttons to a different color?

By the way, I'd prefer if someone first answered the graphics questions, I'm sure I can figure the functionality out on my own.

   import java.awt.BorderLayout;
   import java.awt.Color;
   import java.awt.Container;
   import java.awt.FlowLayout;
   import java.awt.GridLayout;
   import java.awt.event.ActionEvent;
   import java.awt.event.ActionListener;
   import javax.swing.*;
   import java.awt.GridBagConstraints;
   import java.awt.Dimension;

    public class Calculator extends JFrame implements ActionListener
   {  
      JButton button1 = new JButton("1");
      JButton button2 = new JButton("2");
      JButton button3 = new JButton("3");
      JButton button4 = new JButton("4");
      JButton button5 = new JButton("5");
      JButton button6 = new JButton("6");
      JButton button7 = new JButton("7");
      JButton button8 = new JButton("8");
      JButton button9 = new JButton("9");
      JButton button0 = new JButton("0");

      JButton buttonAdd = new JButton("+");
      JButton buttonSub = new JButton("-");
      JButton buttonMult = new JButton("*");
      JButton buttonDiv = new JButton("/");
      JButton buttonEquals = new JButton("=");
      JButton buttonClear = new JButton("C");

      JButton plusOrMinus = new JButton("+/-");
      JButton decimal = new JButton(".");
      JButton squareRoot = new JButton("sqrt.");
      JButton inverse = new JButton("1/x");
      JButton mod = new JButton("%");
      JButton backSpace = new JButton("Backspace");
      JButton clearE = new JButton("CE");

      JButton memoryClear = new JButton("MC");
      JButton memoryRecall = new JButton("MR");
      JButton memoryStore = new JButton("MS");
      JButton memoryAdd = new JButton("M+");

      JPanel jBack = new JPanel();
      JLabel output = new JLabel("0");
      JPanel jSpacing = new JPanel();
      JPanel jMstr = new JPanel();
      JPanel buttonSpace = new JPanel();

      double firstNumber, memoryNumber;
      String opera = "0";
      boolean clear;

       public Calculator()
      {     
         output.setHorizontalTextPosition(JLabel.RIGHT);
         output.setBackground(Color.WHITE);
         output.setOpaque(true);

         getContentPane().add(output, BorderLayout.NORTH);

         jBack.setLayout(new GridLayout(1, 1, 2, 2));
         jBack.add(backSpace);

         jSpacing.setLayout(new GridLayout(1, 2, 2, 2));        
         jSpacing.add(clearE);
         jSpacing.add(buttonClear);

         buttonSpace.setLayout(new GridLayout(4, 5, 2, 2));

         buttonSpace.add(memoryClear);   
         buttonSpace.add(button7);
         buttonSpace.add(button8);
         buttonSpace.add(button9);
         buttonSpace.add(buttonDiv);
         buttonSpace.add(squareRoot);

         buttonSpace.add(memoryRecall);   
         buttonSpace.add(button4);
         buttonSpace.add(button5);
         buttonSpace.add(button6);
         buttonSpace.add(buttonMult);
         buttonSpace.add(inverse);

         buttonSpace.add(memoryStore);         
         buttonSpace.add(button1);
         buttonSpace.add(button2);
         buttonSpace.add(button3);
         buttonSpace.add(buttonSub);
         buttonSpace.add(mod);

         buttonSpace.add(memoryAdd);
         buttonSpace.add(button0);
         buttonSpace.add(plusOrMinus);
         buttonSpace.add(decimal);
         buttonSpace.add(buttonAdd);
         buttonSpace.add(buttonEquals);

         jMstr.setLayout(new BorderLayout());
         jMstr.add(jBack, BorderLayout.WEST);
         jMstr.add(jSpacing, BorderLayout.EAST);
         jMstr.add(buttonSpace, BorderLayout.SOUTH);

         getContentPane().add(jMstr, BorderLayout.SOUTH);

         button1.addActionListener(this);
         button2.addActionListener(this);
         button3.addActionListener(this);
         button4.addActionListener(this);
         button5.addActionListener(this);
         button6.addActionListener(this);
         button7.addActionListener(this);
         button8.addActionListener(this);
         button9.addActionListener(this);
         button0.addActionListener(this);

         buttonAdd.addActionListener(this);
         buttonSub.addActionListener(this);
         buttonMult.addActionListener(this);
         buttonDiv.addActionListener(this);
         buttonEquals.addActionListener(this);
         buttonClear.addActionListener(this);

         plusOrMinus.addActionListener(this);
         decimal.addActionListener(this);
         squareRoot.addActionListener(this);
         inverse.addActionListener(this);
         mod.addActionListener(this);
         backSpace.addActionListener(this);
         clearE.addActionListener(this);

         memoryClear.addActionListener(this);
         memoryRecall.addActionListener(this);
         memoryStore.addActionListener(this);
         memoryAdd.addActionListener(this);

         try
         {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
         }

             catch(Exception e)
            {
            }       

         SwingUtilities.updateComponentTreeUI(jMstr);       
      }

       public void actionPerformed(ActionEvent e)
      {
         double result = 0;

         if(e.getSource() == buttonEquals)
         {
            processEquals();
         }

         if(e.getSource() == button0)
         {
            putDigitOnLabel(0);
         }

         if(e.getSource() == button1)
         {
            putDigitOnLabel(1);
         }

         if(e.getSource() == button2)
         {
            putDigitOnLabel(2);
         }

         if(e.getSource() == button3)
         {
            putDigitOnLabel(3);
         }

         if(e.getSource() == button4)
         {
            putDigitOnLabel(4);
         }

         if(e.getSource() == button5)
         {
            putDigitOnLabel(5);
         }

         if(e.getSource() == button6)
         {
            putDigitOnLabel(6);
         }

         if(e.getSource() == button7)
         {
            putDigitOnLabel(7);
         }

         if(e.getSource() == button8)
         {
            putDigitOnLabel(8);
         }

         if(e.getSource() == button9)
         {
            putDigitOnLabel(9);
         }

         if(e.getSource() == plusOrMinus)
         {
            changeSign();
         }

         if(e.getSource() == decimal)
         {
            addDecimalPoint();
         }

         if(e.getSource() == buttonDiv)
         {
            if(getNumberInDisplay() == 0)
            {
               output.setText("Cannot divide a number by zero.");
            }
            operation("/");
         }

         if(e.getSource() == buttonMult)
         {
            operation("*");
         }

         if(e.getSource() == buttonSub)
         {
            operation("-");
         }

         if(e.getSource() == buttonAdd)
         {
            operation("+");
         }

         if(e.getSource() == squareRoot)
         {
            if(getNumberInDisplay() < 0)
            {
               output.setText("Cannot take the square root of a negative number.");
            }

            double num = Math.sqrt(Double.parseDouble(output.getText()));
            output.setText(Double.toString(num));

         }

         if(e.getSource() == inverse)
         {
            if(getNumberInDisplay() == 0)
            {
               output.setText("Cannot take the inverse of the number zero");
            }
            double num = 1/( Double.parseDouble(output.getText()));
            output.setText(Double.toString(num));
         }

         if(e.getSource() == mod)
         {
            result = getNumberInDisplay() / 100;
            displayResult(result);
         }

         if(e.getSource() == backSpace)
         {


     setTextOnOutput(getStringOnDisplay().substring(0, getStringOnDisplay().length()-1));   


         }

         if(e.getSource() == clearE)
         {
            clearEverythingButOperation();
         }

         if(e.getSource() == buttonClear)
         {
            clearEverything();
         }  

         if(e.getSource() == memoryRecall)
         {
            displayResult(memoryNumber);
         }

         if(e.getSource() == memoryStore)
         {
            memoryNumber = getNumberInDisplay();
         }

         if(e.getSource() == memoryAdd)
         {
            memoryNumber += getNumberInDisplay();
         }   

         if(e.getSource() == memoryClear)
         {
            memoryNumber = 0;
         }                          
      } 

       public void setTextOnOutput(String s)
      {
         output.setText(s);
      }

       public String getStringOnDisplay()
      {
         return output.getText();
      }

       public void putDigitOnLabel(int digit)
      {
         if(clear == true)
         {
            output.setText("");
         }

         if(getStringOnDisplay().indexOf("0") == 0)
         {
            setTextOnOutput(getStringOnDisplay().substring(1));
         }

         output.setText(getStringOnDisplay() + digit);

         clear = false;
      }     

       public void addDecimalPoint()
      {
         if(clear == true)
         {
            setTextOnOutput("");
         }

         if(getStringOnDisplay().indexOf(".") == -1)
         {
            setTextOnOutput(new String(getStringOnDisplay() + "."));
         }
      }

       public void changeSign()
      {
         if(Double.parseDouble(output.getText()) < 0)
         {
            setTextOnOutput(getStringOnDisplay().substring(1));
         }

         if(Double.parseDouble(output.getText()) > 0)
         {
            setTextOnOutput(Double.toString(getNumberInDisplay() * -1));
         }    
      } 

       public void clearEverythingButOperation()
      {
         setTextOnOutput("0");
         clear = true;      
      }

       public void clearEverything()
      {
         setTextOnOutput("0");
         opera = "0";
         firstNumber = 0;
         clear = true;
      }

       public double getNumberInDisplay()
      {
         String stuff = output.getText();
         return Double.parseDouble(stuff);
      }

       public void operation(String s)
      {      
         double number = getNumberInDisplay();

         if(!(opera.equals("0")))
         {         
            double result = processOperator();
            displayResult(result);
            firstNumber = result;
         }

         else
         {
            firstNumber = number;
         }

         clear = true;
         opera = s;
      }

       public void processEquals()
      {
         double result;

         result = processOperator();
         displayResult(result);

         opera = "0";
      }

       public double processOperator()
      {    
         double answer = 0;
         double number = getNumberInDisplay();

         if(opera.equals("*"))
         {

            answer = firstNumber * number;
         }

         if(opera.equals("-"))
         {
            answer = firstNumber - number;
         }

         if(opera.equals("+"))
         {
            answer = firstNumber + number;
         }

         if(opera.equals("/"))
         {
            answer = firstNumber / number;
         }

         return answer;
      }

       public void displayResult(double result)
      {
         setTextOnOutput(Double.toString(result));
         firstNumber = result;
         clear = true;
      }

       public static void main(String args[])
      {
         Calculator f= new Calculator();
         f.setTitle("Windows Calculator");
         f.setSize(300, 300);
         f.pack();
         f.setVisible(true);
         f.setResizable(false);
      } 
   }
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • 2
    Please read up on and then use arrays. It will make your code 1/5th the size and *much* easier for you and us to read, understand and debug. – Hovercraft Full Of Eels Jun 09 '12 at 21:37
  • 2
    If you can figure out how to solve some of the problems, why are you asking here? Start debugging to narrow down the code with the problems. We are not an answer database, we help with PROBLEMS. – Hidde Jun 09 '12 at 21:47

2 Answers2

1

Answer to 1 and 2:

You need to keep track of your operators better probably in a stack or store the information for what you need until you want to "clear out" the history. Here is an example online that makes a similar program.

Java: Example - Simple Calculator

Here are some specifics about a few of the changes needed in your code...

On line 415 in your processEquals() function, you clear the opera variable. This makes it so that pressing the equal sign a second time does nothing. If you comment out that line, it should work better.

On line 390 in your operation(String) function, you get the NumberInTheDisplay() for use in the operation, but you don't hold on to it in the case that they decide to click the equals sign twice. You need to store this value and make it available for processEquals().

In general, when troubleshooting or when adding features, determine the current behavior, and determine the desired behavior and break down the difference into manageable chunks.

Also make a set of unit tests for specific functions and behavior, so you can know when it is working and when it is not.

Beyond that, you will need to debug it on your own. Good luck.

Answer to 3:

How to set the component size with GridLayout? Is there a better way?

Answer to 4:

How to set background color of a button in Java GUI?

Community
  • 1
  • 1
phyatt
  • 18,472
  • 5
  • 61
  • 80
1

To change a component's default font, you could try to use the UIManager methods, though you will need to understand that these may be very Look & Feel dependent and so might not work for each L&F. For instance, if you wanted the JButtons to have a larger Font, you could do:

Font btnFont = UIManager.getFont("Button.font");
float fontSize = 16f;
btnFont = btnFont.deriveFont(fontSize);
UIManager.put("Button.font", btnFont);

I believe that this could would need to be called before any JButtons are created. So one place to call this could be in your main method before creating your Calculator object, or another place could be inside of a static initializer block.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373