Click to See Complete Forum and Search --> : Pass by Value Problem


PleaseNoMoreJava
November 22nd, 2004, 10:21 AM
Hi all,

Im trying to do a simple value passing operation i cant seem to get it working correctly. I have two classes one which produces a value and the other that needs that value to do something with it. I have written the code, although i do not get the right result, when i click the confirm button and enter how many tickets i would like, the showID integer to be passed over to Cost class using method at the bottom of panel class. Heres my code:

Panel Class:
import javax.swing.*;
import java.awt.*;
import javax.swing.JOptionPane;
import java.awt.event.*;

public class Panel extends JFrame{

public JComboBox days, months, years;
private JLabel dateresult;
public String date, day, month, year;
private JTextArea area;
public int num;

public static void main(String[] args)
{
Panel frame = new Panel();
}

public Panel()
{
String[] Month = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
String[] Year = {"2004"};
String [] Day = new String[32];
for(int i = 1; i < 32; i++) {
Day[i] = Integer.toString(i);
}

JButton okbutton;
JButton confirmbutton;

JFrame frame = new JFrame();
frame.setLocation(100,100);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
JPanel primary = new JPanel(new FlowLayout(FlowLayout.CENTER,30000,5));
primary.setPreferredSize(new Dimension(500,500));
JPanel datecombos = new JPanel(new FlowLayout(FlowLayout.CENTER,10,10));
days = new JComboBox(Day);
days.addItemListener(new SelectButton(datecombos));
days.setSelectedIndex(1);
months = new JComboBox(Month);
months.addItemListener(new SelectButton(datecombos));
years = new JComboBox(Year);
years.addItemListener(new SelectButton(datecombos));
datecombos.add (days);
datecombos.add (months);
datecombos.add (years);
Cost cost;
cost = new Cost();
cost.BookingType();
JPanel showinfo = new JPanel();
primary.add (datecombos);
primary.add (showinfo);
dateresult = new JLabel();
okbutton = new JButton("SELECT");
okbutton.addActionListener(new SelectButton(datecombos));
datecombos.add (okbutton);
area = new JTextArea();
primary.add (cost);
showinfo.add (area);
frame.getContentPane().add(primary, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
}

public class SelectButton implements ItemListener, ActionListener {

JPanel parent;
public SelectButton(JPanel p){parent = p;}
public void actionPerformed(ActionEvent e)
{
String showID;

day = (String) days.getSelectedItem();
month = (String) months.getSelectedItem();
year = (String) years.getSelectedItem();

if (day != "1" || month != "Apr" || year != "2004")
{
JOptionPane.showMessageDialog(parent, "There are no showings Available for this Date. " +
"Please Select Again","Error",
JOptionPane.ERROR_MESSAGE);
}
else
{
dateresult.setText("Date Selected : " +day+" "+month+" "+year);

try //select 1, 2 or 3
{
showID = JOptionPane.showInputDialog(parent, "Enter A Show ID Please.");
num = Integer.parseInt(showID);

if (num == 1)
{
JOptionPane.showMessageDialog(parent, " bla bla bla");
area.setText(" ");
}
else if (num == 2)
{
JOptionPane.showMessageDialog(parent,"bla bla bla");
area.setText("");
}
else if (num == 3)
{
JOptionPane.showMessageDialog(parent,"bla bla bla");
area.setText("");
}
else
{
JOptionPane.showMessageDialog(parent,"You have not picked correctly" +
" Please Select Again","Error",
JOptionPane.ERROR_MESSAGE);
}
}
catch ( NumberFormatException ex )
{
JOptionPane.showMessageDialog(parent, "Non Numerical Data Exception.");
System.exit( 0 ); // Exits Program
}
}
}

public void itemStateChanged(ItemEvent e) { }
}

public void getnum(int num1)
{
num = num1;

}
}

Cost Class
import javax.swing.*;
import java.awt.*;
import javax.swing.JOptionPane;
import java.awt.event.*;
import java.awt.*;
import javax.swing.text.*;
import javax.swing.event.*;

public class Cost extends JPanel implements ItemListener, ActionListener {

public String[] type = {"Select", "Adult", "Child", "Student"};
public String typechosen, ticketno;
public JComboBox typecombo, numbercombo;
public int ticketcost, number, totalcost;
private JLabel typeresult;

public int num1;

public int screen1 = 50;
public int screen2 = 75;
public int screen3 = 100;

public JTextField tickettext;
public JButton ticketbutton, confirmbutton;

/** Creates a new instance of BookingInfo */
public void BookingType() {

JPanel typeinfo = new JPanel(new FlowLayout(FlowLayout.CENTER,30000,5));
typeinfo.setBorder(BorderFactory.createLoweredBevelBorder());
typeinfo.setBackground (Color.yellow);
typeinfo.setPreferredSize(new Dimension(200,100));
JLabel costlabel1 = new JLabel ("Select Ticket Type");
costlabel1.setFont(new Font("Serif", Font.BOLD, 14));
costlabel1.setForeground(Color.black);
typecombo = new JComboBox(type);
typecombo.addItemListener(this);
typeinfo.add(costlabel1);
typeinfo.add(typecombo);
typeresult = new JLabel();
typeinfo.setVisible(true);
add(typeinfo);
JPanel okPanel = new JPanel();
okPanel.setBorder(BorderFactory.createLoweredBevelBorder());
okPanel.setBackground (Color.red);
okPanel.setPreferredSize(new Dimension(500,60));
confirmbutton = new JButton("CONFIRM BOOKING");
confirmbutton.addActionListener(this);
typeinfo.add(confirmbutton);

}

public void itemStateChanged( ItemEvent event )
{
typechosen = (String) typecombo.getSelectedItem();

if ( typechosen.equals("Adult"))
{
ticketcost = 5;
}
else if ( typechosen.equals("Child"))
{
ticketcost = 3;
}
else if ( typechosen.equals("Student"))
{
ticketcost = 4;
}
}

public void actionPerformed(ActionEvent e)
{
try
{
ticketno = JOptionPane.showInputDialog(Cost.this, "Please enter the number of tickets required. Thanks");
number = Integer.parseInt(ticketno);
totalcost = ticketcost * number;
}
catch ( NumberFormatException ex )
{
JOptionPane.showMessageDialog(Cost.this, "Non Numerical Data Exception.");
System.exit( 0 ); // Exits Program
}

Panel cust;
cust = new Panel();
cust.getnum(num1);

System.out.println(num1); //this should print passed value out

if (num1 > screen1)
{
JOptionPane.showMessageDialog(Cost.this, "Booking Accepted");
}
else if (num1 > screen2)
{
JOptionPane.showMessageDialog(Cost.this, "Booking Accepted");
}
else if (num1 > screen3)
{
JOptionPane.showMessageDialog(Cost.this, "Booking Accepted");
}
else
{
JOptionPane.showMessageDialog(Cost.this, "Booking Not Accepted");
}
}
}

I have highlighted areas of code that are the problem areas.

Does anyone have any ideas why im not getting the desired result ?

Thanks

mikeBarr81
November 22nd, 2004, 11:25 AM
the showID integer to be passed over to Cost class using method at the bottom of panel class

So to make sure I have this straight, you want a value from the Panel class to be passed to the Cost class. If so, then you seem to be a bit confused about what your methods are doing.

public void getnum(int num1)
{
num = num1;

}
You have named this method getnum, but really you should have named it setnum. The method takes an integer named num1 as a parameter, and it makes the class variable named num equal to that value. It doesn't "get" any values at all, it sets one.

Instead, you want a method that returns a value. They keyword "void" that you used means that the method does not return a value, which is not what you want. Instead, you want the method to return an int. You need to make several changes to the method to do that.

public int getNum() //change void to int, no parameters needed
{
return num; //return keyword used to pass a value back
}

cjard
November 22nd, 2004, 12:39 PM
i see why you are thinking like this; you may be incorrectly understanding that the sequence of letters "GET" has some meaning to java; it doesnt. java doesnt care what spoken-language you program in..

youre actually expecting this to work in a pass-by-reference sense of the word. pass by value cannot be used to populate a variable in this context

i'll pick on an example that works as per your expectation:

byte[] buffer = new byte[4096];
inputStream.read(buffer);


the inputStream is a source of bytes. when you pass the buffer into the read method, the read method will fill it up. after it returns, the buffer will be filled with data.
the read() method works this way by design, but it operates on objects. a byte[] is an object, and is hence ALWAYS passed by reference. this is the ONLY reason that doing it like this, can work for a method like read(), because the method argument is an OBJECT.

primitive variables dont work this way; they always pass by value. pass by value means: if you have a variable in memory that is holding the number 3, and you pass it to a method.. then a copy of the number 3 is given to the method. the method can change it as much as it likes, it wont change the original value. like giving a document to your friend on a floppy disk.. he can change it as much as he likes and your copy is unaffected.
primitive variables are always passed this way. remember this. it is one of the unbendable truths about java.

PleaseNoMoreJava
November 22nd, 2004, 02:53 PM
Hi all,

thanks for taking a look at this and explaining to me about what i need. I have changed my method for returning the value like so:

public int getnum()
{
return num;
}

which should return the int num which has been given a value set in the code above.

ok so now i have a return method in my panel class, i think i am calling that method incorrectly as it duplicates the whole panel class..not what i want if you catch my drift...

i call it in the cost class like so
Panel cust;
cust = new Panel();
num1 = cust.getnum();

System.out.println(cust.getnum());

if (num1 > screen1)
{
//do something with num etc

i think this is still wrong because im still getting zero result.

sorry for being a pain in the arse....