How to implement Global variables in java which can be shared acrossseveral files ?

A

aks_java

Hi, I've been working on a java program that implements a calculator.
There are following modules in my program:

- Calculator.java : contains main method, creates a calculator
instance.
- calcGUI.java: Builds the basic calculator GUI.
- ActionCalculator.java: Implements action listener class.
- Operations.java Implements the operations and does all the
calculations on operands depending upon the operator used.

The problem is that I can't get this program to work and it seems the
calculator object that has been created in Calculator.java cannot be
accessed in ActionCalculator.java and Operations.java even though the
object has been declared as a public static.

Here are the modules:

****************** Calculator.java*****************************

package calculator;

public class Calculator {

public static calcGUI calculator;

public static void main (String args[]) {
calculator = new calcGUI();
calculator.setVisible( true );
}
}


*********************calcGUI.java**********************************

package calculator;

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

public class calcGUI extends JFrame {
public JTextField displayField;
public JLabel memRegLabel;
public String memRegVal = "";
public double prevValue = 0;
public String operatorUsed = "=";
public boolean resetFlag = false;
public calcGUI () {
super ();
setSize( 400, 200 );
setDefaultCloseOperation( EXIT_ON_CLOSE );
Container cont = getContentPane();
displayField = new JTextField("0", 12);
cont.setLayout( new BoxLayout( cont, BoxLayout.Y_AXIS ) );
cont.add( displayField = new JTextField( "0", 12 ) );
displayField.setHorizontalAlignment( JTextField.RIGHT );

JPanel panel1 = new JPanel();
panel1.setLayout( new BoxLayout( panel1, BoxLayout.X_AXIS ) );
cont.add( panel1 );
JPanel panel2 = new JPanel();
panel2.setLayout( new BoxLayout( panel2, BoxLayout.Y_AXIS ) );
panel1.add( panel2 );
JPanel panel3 = new JPanel();
panel3.setLayout( new GridLayout( 1, 23) );
panel3.add( memRegLabel = new JLabel( memRegVal = "" ) );
memRegLabel.setHorizontalAlignment( SwingConstants.CENTER );
panel3.add( new JButton( "Backspace" ) );
panel3.add( new JButton( "CE" ) );
panel3.add( new JButton( "C" ) );
panel2.add( panel3 );
JPanel panel4 = new JPanel();
panel4.setLayout( new GridLayout( 4, 6) );
panel4.add( new JButton( "MC" ) );
panel4.add( new JButton( "7" ) );
panel4.add( new JButton( "8" ) );
panel4.add( new JButton( "9" ) );
panel4.add( new JButton( "/" ) );
panel4.add( new JButton( "" ) );
panel4.add( new JButton( "MR" ) );
panel4.add( new JButton( "4" ) );
panel4.add( new JButton( "5" ) );
panel4.add( new JButton( "6" ) );
panel4.add( new JButton( "*" ) );
panel4.add( new JButton( "sqrt" ) );
panel4.add( new JButton( "MS" ) );
panel4.add( new JButton( "1" ) );
panel4.add( new JButton( "2" ) );
panel4.add( new JButton( "3" ) );
panel4.add( new JButton( "-" ) );
panel4.add( new JButton( "1/x" ) );
panel4.add( new JButton( "M+" ) );
panel4.add( new JButton( "0" ) );
panel4.add( new JButton( "+/-" ) );
panel4.add( new JButton( "." ) );
panel4.add( new JButton( "+" ) );
panel4.add( new JButton( "=" ) );
panel2.add( panel4 );
cont.add( panel1 );

ActionCalculator a = new ActionCalculator();

for( Component comp : panel3.getComponents())
{
if( comp.getClass().toString().matches( ".*JButton.*" ) )
((JButton) comp).addActionListener( a );
}
for( Component comp : panel4.getComponents() )
{
((JButton) comp).addActionListener( a );
}
}
}

****************************ActionCalculator.java***************************

package calculator;

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

public class calcGUI extends JFrame {
public JTextField displayField;
public JLabel memRegLabel;
public String memRegVal = "";
public double prevValue = 0;
public String operatorUsed = "=";
public boolean resetFlag = false;
public calcGUI () {
super ();
setSize( 400, 200 );
setDefaultCloseOperation( EXIT_ON_CLOSE );
Container cont = getContentPane();
displayField = new JTextField("0", 12);
cont.setLayout( new BoxLayout( cont, BoxLayout.Y_AXIS ) );
cont.add( displayField = new JTextField( "0", 12 ) );
displayField.setHorizontalAlignment( JTextField.RIGHT );

JPanel panel1 = new JPanel();
panel1.setLayout( new BoxLayout( panel1, BoxLayout.X_AXIS ) );
cont.add( panel1 );
JPanel panel2 = new JPanel();
panel2.setLayout( new BoxLayout( panel2, BoxLayout.Y_AXIS ) );
panel1.add( panel2 );
JPanel panel3 = new JPanel();
panel3.setLayout( new GridLayout( 1, 23) );
panel3.add( memRegLabel = new JLabel( memRegVal = "" ) );
memRegLabel.setHorizontalAlignment( SwingConstants.CENTER );
panel3.add( new JButton( "Backspace" ) );
panel3.add( new JButton( "CE" ) );
panel3.add( new JButton( "C" ) );
panel2.add( panel3 );
JPanel panel4 = new JPanel();
panel4.setLayout( new GridLayout( 4, 6) );
panel4.add( new JButton( "MC" ) );
panel4.add( new JButton( "7" ) );
panel4.add( new JButton( "8" ) );
panel4.add( new JButton( "9" ) );
panel4.add( new JButton( "/" ) );
panel4.add( new JButton( "" ) );
panel4.add( new JButton( "MR" ) );
panel4.add( new JButton( "4" ) );
panel4.add( new JButton( "5" ) );
panel4.add( new JButton( "6" ) );
panel4.add( new JButton( "*" ) );
panel4.add( new JButton( "sqrt" ) );
panel4.add( new JButton( "MS" ) );
panel4.add( new JButton( "1" ) );
panel4.add( new JButton( "2" ) );
panel4.add( new JButton( "3" ) );
panel4.add( new JButton( "-" ) );
panel4.add( new JButton( "1/x" ) );
panel4.add( new JButton( "M+" ) );
panel4.add( new JButton( "0" ) );
panel4.add( new JButton( "+/-" ) );
panel4.add( new JButton( "." ) );
panel4.add( new JButton( "+" ) );
panel4.add( new JButton( "=" ) );
panel2.add( panel4 );
cont.add( panel1 );

ActionCalculator a = new ActionCalculator();

for( Component comp : panel3.getComponents())
{
if( comp.getClass().toString().matches( ".*JButton.*" ) )
((JButton) comp).addActionListener( a );
}
for( Component comp : panel4.getComponents() )
{
((JButton) comp).addActionListener( a );
}
}
}


************************Operations.java***************************************

package calculator;

public class Operations {
public double calculateResult() {
double totalVal = calculator.prevValue;
double val2 = Double.parseDouble
(calculator.displayField.getText());

if (calculator.operatorUsed.equals("+")) {
totalVal += val2;
}
if (calculator.operatorUsed.equals("-")) {
totalVal -= val2;
}
if (calculator.operatorUsed.equals("/")) {
totalVal /= val2;
}
if (calculator.operatorUsed.equals("*")) {
totalVal *= val2;
}
if (calculator.operatorUsed.equals("=")) {
totalVal = val2;
}
return totalVal;
}
}
 
A

aks_java

I'm sorry, the code for ActionCalculator.java is:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package calculator;

/**
*
* @author Owner
*/
import java.awt.event.*;
import javax.swing.*;

public class ActionCalculator implements ActionListener {
private Operations operations = new Operations ();
public void actionPerformed(ActionEvent event) {
String pressedButton = ((JButton) event.getSource()).getText
();

if (pressedButton.equals("C")) {
calculator.displayField.setText("0");
calculator.operatorUsed = "=";
calculator.prevValue = 0;
calculator.resetFlag = false;
return;
}
if (pressedButton.equals("CE")) {
calculator.displayField.setText("0");
calculator.resetFlag = false;
return;
}
try {
Double.parseDouble(calculator.displayField.getText());
} catch (Exception e) {
calculator.resetFlag = true;
return;
}
for (int i = 0; i < 10; i++) {
if (pressedButton.equals("" + i)) {
if (calculator.resetFlag ||
calculator.displayField.getText().equals("0")) {
calculator.displayField.setText("");
}
calculator.displayField.setText
(calculator.displayField.getText() + i);
calculator.resetFlag = false;
return;
}
}
if (pressedButton.equals("")) {
return;
}
if (pressedButton.equals("MR")) {
if (!calculator.memRegVal.equals("")) {
calculator.displayField.setText(calculator.memRegVal);
}
return;
}
if (pressedButton.equals("MS")) {
calculator.memRegVal = calculator.displayField.getText();
calculator.memRegLabel.setText("M");
return;
}
if (pressedButton.equals("MC")) {
calculator.memRegLabel.setText(calculator.memRegVal = "");
return;
}
if (pressedButton.equals("M+")) {
if (!calculator.memRegVal.equals("")) {
calculator.memRegVal = "" + (Double.parseDouble
(calculator.memRegVal) + Double.parseDouble
(calculator.displayField.getText()));
} else {
calculator.memRegVal = calculator.displayField.getText
();
}
calculator.memRegLabel.setText("M");
return;
}
if (pressedButton.equals("Backspace")) {
String displayedText = calculator.displayField.getText();
if (displayedText.length() > 0) {
displayedText = displayedText.substring(0,
displayedText.length() - 1);
}
if (displayedText.length() == 0) {
displayedText = "0";
}
calculator.displayField.setText(displayedText);
calculator.resetFlag = false;
return;
}
if (pressedButton.equals(".")) {
if (!calculator.displayField.getText().contains(".")) {
calculator.displayField.setText
(calculator.displayField.getText() + ".");
}
calculator.resetFlag = false;
return;
}
if (pressedButton.equals("+/-")) {
double val = Double.parseDouble
(calculator.displayField.getText());
calculator.displayField.setText("" + -val);
calculator.resetFlag = false;
return;
}

if (pressedButton.equals("=")) {
calculator.prevValue = operations.calculateResult();
calculator.operatorUsed = "=";
calculator.displayField.setText("" +
calculator.prevValue);
calculator.resetFlag = true;
return;
}

if (pressedButton.equals("+")) {
calculator.prevValue = operations.calculateResult();
calculator.operatorUsed = "+";
calculator.displayField.setText("" +
calculator.prevValue);
calculator.resetFlag = true;
return;
}

if (pressedButton.equals("-")) {
calculator.prevValue = operations.calculateResult();
calculator.operatorUsed = "-";
calculator.displayField.setText("" +
calculator.prevValue);
calculator.resetFlag = true;
return;
}

if (pressedButton.equals("/")) {
calculator.prevValue = operations.calculateResult();
calculator.operatorUsed = "/";
calculator.displayField.setText("" +
calculator.prevValue);
calculator.resetFlag = true;
return;
}

if (pressedButton.equals("*")) {
calculator.prevValue = operations.calculateResult();
calculator.operatorUsed = "*";
calculator.displayField.setText("" +
calculator.prevValue);
calculator.resetFlag = true;
return;
}

if (pressedButton.equals("sqrt")) {
double totalVal = Math.sqrt(Double.parseDouble
(calculator.displayField.getText()));
System.out.println("sqrt(" +
calculator.displayField.getText() + ") = " + totalVal);
calculator.displayField.setText("" + totalVal);
return;
}

if (pressedButton.equals("1/x")) {

double totalVal = 1 / Double.parseDouble
(calculator.displayField.getText());
System.out.println("1 / " + calculator.displayField.getText
() + " = " + totalVal);
calculator.displayField.setText("" + totalVal);
return;
}
calculator.displayField.setText(pressedButton);
}
}
 
M

Mark Space

aks_java said:
The problem is that I can't get this program to work and it seems the
calculator object that has been created in Calculator.java cannot be
accessed in ActionCalculator.java and Operations.java even though the
object has been declared as a public static.

public class Calculator {

public static calcGUI calculator;

public class Operations {
public double calculateResult() {
double totalVal = calculator.prevValue;

<snip>

I assume you mean "calculator" in the line above. You need to identify
the name of the class here. It should be
"Calculator.calculator.preValue". Probably you have the same problem in
ActionCalculator.

"calculator" by itself refers to a variable in Operations, which of
course there is none.
 
R

Roedy Green

if (calculator.operatorUsed.equals("+")) {

You should avoid global variables. Others may give you hints on how to
refactor to avoid them.

But your technical problem is you used plain calculator instead of
Calculator.calculator. Javac was looking for a calculator variable in
the current class.

--
Roedy Green Canadian Mind Products
http://mindprod.com

Never discourage anyone... who continually makes progress, no matter how slow.
~ Plato 428 BC died: 348 BC at age: 80
 
A

aks_java

You should avoid global variables. Others may give you hints on how to
refactor to avoid them.

But your technical problem is you used plain calculator instead of
Calculator.calculator.  Javac was looking for a calculator variable in
the current class.

Yes, now its working but I just can't figure out how to avoid global
variables. I mean if I create a calculator instance that has to be
used across the I also want to totally separate the business logic
from UI logic so that I'm able to use the same business logic (+, - ,
* , / etc operations) for a command line calculator.
 
L

Lew

aks_java said:
Yes, now its working but I just can't figure out how to avoid global
variables. I mean if I create a calculator instance that has to be
used across the I also want to totally separate the business logic
from UI logic so that I'm able to use the same business logic (+, - ,
* , / etc operations) for a command line calculator.

But you have the answer already. Static variables are Java's
equivalent of global variables.

You can refer to 'Calculator.calculator' globally. That gives you
what you wanted.

I should not tell you about 'import static'. That will only tempt you
to refer to 'calculator' in your code without the class name, thus
making it look more like a global to your eyes but confusing everyone
else who might think that 'calculator' is local to the class that uses
it.

You should make the static global variable 'final'.
 
M

Mark Space

aks_java said:
Yes, now its working but I just can't figure out how to avoid global
variables.


Ah, well that is a good question. First, you might want to decide what
your business logic is, and what the model is. See MVC:

<http://en.wikipedia.org/wiki/Model-view-controller>

A typical controller has a model and a view, but they are not global,
they are instance variables:

public class Controller {
Model model;
View view; //JFrame or JPanel

public Controller( Model model, View view ) {
...
}
...
}


I would build these objects on the EDT, along with the gui. It's normal
to need the controller and the view at the same time. Here's a new main
method / entry point:

public class Calculator {

public static void main( String... args ) {
javax.swing.SwingUtilities.invokeLater( new Runnable () {
public void run() {
createAndShowGui();
}
});
}
private void createAndShowGui() {
View v = new MyView();
Model m = new MyModel();
Controller c = new Controller( m, v);
//... more later
}
}

I think your model could be simple for a calculator program. Mostly you
just manipulate the value on the screen. So maybe a simple double value
is enough.

public class MyModel {
private double screenValue;
public double getValue() { return screenValue; }
public void setValue(double d) {screenValue = d;}
}

Now you need to connect the View to the Model via the controller.
Here's where that "more later" bit in the comment above comes in


v.addListener( new Controller.CalcActionListner() );

Where CalcActionListener is

public class Controller {

.... same as above, plus....

static class CalcActionListener implements ActionListener {

public void actionPerformed( ActionEvent e ) {
String ac = e.getActionCommand();
if( "+".eqauls(ac) ) {
// add something and update Model
double sum = model.getValue() + model.getValue();
model.setValue( sum );
view.updateScreen( sum );
}
else if ...
}
}
}

Etc. There I've shown one way of binding the objects together. Now
that I think about it, one double isn't enough, because you need two
values, not one, for most math operations. And you need a way to
accumulate digits (characters?) as they are typed. So the thing is
going to be a bit more complicated than shown here.

Also a real model updates (via observer pattern) a view itself, not
usually the controller (action listener), but this model is so simple
you can skip that if you like.

This should be something you can break up into smaller bits and start
testing. That's what MVC is for, is to chunk the parts up so they can
be worked on and tested separately. I hope this gets you started.

Note: no code here was checked for correct syntax or semantics, but it
should be close.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,708
Messages
2,569,348
Members
44,663
Latest member
XiomaraBla

Latest Threads

Top