Problem with object having a value different to what the constructor s

  • (2 Pages)
  • +
  • 1
  • 2

23 Replies - 841 Views - Last Post: 09 March 2011 - 11:39 PM Rate Topic: -----

#1 DinkinFlicka  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 27
  • Joined: 19-February 11

Problem with object having a value different to what the constructor s

Posted 05 March 2011 - 04:36 PM

I don't even know where to begin asking this question.

The assignment calls for an Applet that displays the total cost of services checked off.

I made a new class VetJCheckBox that extends JCheckBox. In the constructor, I added the price as one of the parameters. In the itemEventChanged() method, whenever I set a new totalCost using the getSelectionCost() method of VetJCheckBox, it uses the same "cost" value no matter what box is selected. The cost value used is the "puppyVisit" cost. I'm guessing this is because it is the last object created, but I have no idea why.

Also, am I correctly using "this" and the static declarations?

No errors occur when compiling.

Let me know if I can be any more clear.

Veterinarian Class:
/*
* 
* 3/2/2011
* Veterinarian.java
*/

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

public class Veterinarian extends JApplet implements ItemListener{

	double totalCost;

	JLabel companyName = new JLabel("Veterinarian" );

	JLabel selectService = new JLabel("Select service you want:");

	JLabel totalCostLabel = new JLabel("Total cost: $" + totalCost);

	VetJCheckBox heartWorm = new VetJCheckBox("Heart Worm - $50.00", false, 50);
	VetJCheckBox emergencyService = new VetJCheckBox("Emergency Service - $40.97", false, 40.97);
	VetJCheckBox hospitalization = new VetJCheckBox("Hospitalization - $75.55", false, 75.55);
	VetJCheckBox dentistry = new VetJCheckBox("Dentistry - $253.38", false, 253.38);
	VetJCheckBox xrays = new VetJCheckBox("X-Rays - $68.54", false, 68.54);
	VetJCheckBox stitches = new VetJCheckBox("Stitches - $15.45", false, 15.45);
	VetJCheckBox labWork = new VetJCheckBox("Lab Work - $72.00", false, 72.00);
	VetJCheckBox prescription = new VetJCheckBox("Prescription - $32.50", false, 32.50);
	VetJCheckBox puppyVisit = new VetJCheckBox("Puppy Visit - $35.45", false, 35.45);
	
	public void init() {
		setLayout(new FlowLayout());

		add(companyName);
		add(selectService);
		add(totalCostLabel);
		add(heartWorm);
		add(emergencyService);
		add(hospitalization);
		add(dentistry);
		add(xrays);
		add(stitches);
		add(labWork);
		add(prescription);
		add(puppyVisit);
		
		
		heartWorm.addItemListener(this);
		emergencyService.addItemListener(this);
		hospitalization.addItemListener(this);
		dentistry.addItemListener(this);
		xrays.addItemListener(this);
		stitches.addItemListener(this);
		labWork.addItemListener(this);
		prescription.addItemListener(this);
		puppyVisit.addItemListener(this);

		}

	public void itemStateChanged(ItemEvent e) {
		Object source = e.getItemSelectable();
		
		if (source == heartWorm) {
			totalCost += heartWorm.getSelectionCost(e);
			displayTotalCost();
		}

		if (source == emergencyService) {
			totalCost += emergencyService.getSelectionCost(e);
			displayTotalCost();
		}
		
		if (source == hospitalization) {
			totalCost += hospitalization.getSelectionCost(e);
			displayTotalCost();
		}		
		
		if (source == dentistry) {
			totalCost += dentistry.getSelectionCost(e);
			displayTotalCost();
		}		

		if (source == xrays) {
			totalCost += xrays.getSelectionCost(e);
			displayTotalCost();
		}

		if (source == stitches) {
			totalCost += stitches.getSelectionCost(e);
			displayTotalCost();
		}
		
		if (source == labWork) {
			totalCost += labWork.getSelectionCost(e);
			displayTotalCost();
		}		
		
		if (source == prescription) {
			totalCost += prescription.getSelectionCost(e);
			displayTotalCost();
		}		
		
		if (source == puppyVisit) {
			totalCost += puppyVisit.getSelectionCost(e);
			displayTotalCost();
		}	
	
	}
	
	private void displayTotalCost() {
		totalCostLabel.setText("Total cost: $" + totalCost);
		}
}





VetJCheckBox class:

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

public class VetJCheckBox extends JCheckBox {

	static double cost;
	
	public VetJCheckBox(String text, boolean selected, double cost) {
		this.setLabel(text);
		this.setSelected(selected);
		this.cost = cost;
	}
	
	public double getSelectionCost(ItemEvent e) { // Returns either a positive or negative value of the cost of the instance that called the method
		if (e.getStateChange() == ItemEvent.SELECTED) {
				return this.cost;
			} else if (e.getStateChange() == ItemEvent.DESELECTED) {
				return (-this.cost);
			}
		else {
			return 0;
			}
		}
	}


This post has been edited by DinkinFlicka: 05 March 2011 - 04:37 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Problem with object having a value different to what the constructor s

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4189
  • View blog
  • Posts: 11,863
  • Joined: 18-April 07

Re: Problem with object having a value different to what the constructor s

Posted 05 March 2011 - 04:59 PM

Don't make the "Cost" variable in VetJCheckBox static. Make it a private variable to the class. When you make it static you are saying that all instances of VetJCheckBox have access to that variable. So when you created all your objects, the puppy visit was last and thus modified the variable that all share.

When we make it private, each instance of VetJCheckBox gets its own cost variable to itself that no other instances of the class can access or modify. In other words, they don't share the variable like they do when you use "static".

Read up more on the idea of "static variables" to get more information. Enjoy!

:)
Was This Post Helpful? 1
  • +
  • -

#3 DinkinFlicka  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 27
  • Joined: 19-February 11

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 08:14 AM

View PostMartyr2, on 05 March 2011 - 04:59 PM, said:

Don't make the "Cost" variable in VetJCheckBox static. Make it a private variable to the class. When you make it static you are saying that all instances of VetJCheckBox have access to that variable. So when you created all your objects, the puppy visit was last and thus modified the variable that all share.

When we make it private, each instance of VetJCheckBox gets its own cost variable to itself that no other instances of the class can access or modify. In other words, they don't share the variable like they do when you use "static".

Read up more on the idea of "static variables" to get more information. Enjoy!

:)


Thanks. Is there are better way to go about writing a program like this?
Was This Post Helpful? 0
  • +
  • -

#4 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 12:14 PM

Your actual

else  
   {
      return 0;
   }



in your CheckBox class is useless, the button can only be selected or not
And not using -cost would be a good idea, I simplified it a bit
as, in your actionPerformed() would be easier to set cotalCost to 0 and then just add the ones that need to be add

No need to repeat displayTotalCost() 15 times, one will be enough

	public void itemStateChanged(ItemEvent e) {
		Object source = e.getItemSelectable();
		totalCost = 0;
		if (source == heartWorm) {
			totalCost += heartWorm.getSelectionCost(e);
		}

		if (source == emergencyService) {
			totalCost += emergencyService.getSelectionCost(e);
		}
		
		if (source == hospitalization) {
			totalCost += hospitalization.getSelectionCost(e);
		}		
		
		if (source == dentistry) {
			totalCost += dentistry.getSelectionCost(e);
		}		

		if (source == xrays) {
			totalCost += xrays.getSelectionCost(e);
		}

		if (source == stitches) {
			totalCost += stitches.getSelectionCost(e);
		}
		
		if (source == labWork) {
			totalCost += labWork.getSelectionCost(e);
		}		
		
		if (source == prescription) {
			totalCost += prescription.getSelectionCost(e);
		}		
		
		if (source == puppyVisit) {
			totalCost += puppyVisit.getSelectionCost(e);
		}	
	
		displayTotalCost();
	}



public class VetJCheckBox extends JCheckBox {

	double cost;
	
	public VetJCheckBox(String text, boolean selected, double cost) {
		super(text);
		setSelected(selected);
		this.cost = cost;
	}
	
	public double getSelectionCost(ItemEvent e) { // Returns either a positive or negative value of the cost of the instance that called the method
        if(isSelected())
        	return cost;
        return 0.0;
		}
	}


Was This Post Helpful? 1
  • +
  • -

#5 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10186
  • View blog
  • Posts: 37,613
  • Joined: 27-December 08

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 04:22 PM

public class VetJCheckBox extends JCheckBox 


The JCheckBoxes shouldn't have the responsibility of managing the cost. Always separate your program's user interface from the data. The JCheckBoxes should store the item names, and you should have a HospitalBill class along with a HospitalProcedure class. For each JCheckBox selected, add an appropriate HospitalProcedure object to the HospitalBill object.
Was This Post Helpful? 1
  • +
  • -

#6 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 06:24 PM

OK son, here it is how Macosxnerd101 wants to see it implemented :) Even if I think he is more catholic than the pope :)

/*
 * 
 * 3/2/2011
 * Veterinarian.java
 */

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class Vetenerian extends JApplet implements ItemListener{

	double totalCost;

	JLabel companyName = new JLabel("Veterinarian" );
	JLabel selectService = new JLabel("Select service you want:");
	JLabel totalCostLabel = new JLabel("Total cost: $" + totalCost);

	String[] vetServices = {"Heart Worm", "Emergency Services"};
	double[] cost = {50.0, 40.97};
	JCheckBox[] cb = new JCheckBox[vetServices.length];
	VetService[] vs = new VetService[vetServices.length];


	public void init() {
		setLayout(new FlowLayout());

		add(companyName);
		add(selectService);
		add(totalCostLabel);


		// build VetService objects
		for(int i = 0; i < vetServices.length; i++) {
			vs[i] = new VetService(vetServices[i], cost[i]);
			cb[i] = vs[i].getCheckBox();
			add(cb[i]);
			cb[i].addItemListener(this);
		}

	}

	public void itemStateChanged(ItemEvent e) {
		totalCost = 0;
		for(int i = 0; i < cb.length; i++) {
           if(cb[i].isSelected())
        	   totalCost += vs[i]getCost();
		}
		displayTotalCost();
	}

	private void displayTotalCost() {
		totalCostLabel.setText("Total cost: $" + totalCost);
	}

	class VetService {
		String name;
		double cost;

		VetService(String name, double cost) {
			this.name = name;
			this.cost = cost;
		}
 
		double getCost() {
			return cost;
		}

		JCheckBox getCheckBox() {
			JCheckBox cb = new JCheckBox(name + " - " + cost);
			return cb;
		}
	}

}


Was This Post Helpful? 1
  • +
  • -

#7 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 06:44 PM

Still, actuyally, I must admit a better way of doing it :)
In my example I used only 2 services, you will have to add the others, but the idea stays the same
Was This Post Helpful? 1
  • +
  • -

#8 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10186
  • View blog
  • Posts: 37,613
  • Joined: 27-December 08

Re: Problem with object having a value different to what the constructor s

Posted 06 March 2011 - 06:52 PM

I may be more catholic than the pope here, but at least I am preaching for my parrish. :)
Was This Post Helpful? 1
  • +
  • -

#9 DinkinFlicka  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 27
  • Joined: 19-February 11

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 04:27 PM

What is a good way to format the layout of the components on the appet?

I've been using FlowLayout but can't seem to figure out how to get things to go to new lines. I tried giving each component a coordinate, but things would disappear and reappear when I scrolled the mouse over the window.
Was This Post Helpful? 0
  • +
  • -

#10 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10186
  • View blog
  • Posts: 37,613
  • Joined: 27-December 08

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 05:43 PM

Don't assign coordinates to JComponents. Let the LayoutManagers do their jobs. The major ones are FlowLayout, GridLayout, BorderLayout, and BoxLayout. If you want an a*b grid, with no more than b JComponents per row, then GridLayout is probably the LayoutManager you want to look at. Note that it does not respect the size of the JComponents and may resize them.
Was This Post Helpful? 1
  • +
  • -

#11 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8315
  • View blog
  • Posts: 31,836
  • Joined: 06-March 08

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 08:59 PM

Make a GridLayout(11, 1); // I say 11 but can be more actualkly vetServices.length + 4
Was This Post Helpful? 1
  • +
  • -

#12 DinkinFlicka  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 27
  • Joined: 19-February 11

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 09:37 PM

View Postmacosxnerd101, on 07 March 2011 - 05:43 PM, said:

Note that it does not respect the size of the JComponents and may resize them.


Is there anyway to give the JComponents a size? For example, if I have a button and don't want it to take up the entire box, can I fix that?
Was This Post Helpful? 0
  • +
  • -

#13 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10186
  • View blog
  • Posts: 37,613
  • Joined: 27-December 08

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 09:44 PM

You could add the JComponents to individual JPanels, and add the JPanels to the cells in the GridLayout. That will prevent their dimmensions from being distorted. Really though, you shouldn't be modifying a JComponent's size unless it is either a top-level container or you have very good reason and know what you are doing.
Was This Post Helpful? 0
  • +
  • -

#14 DinkinFlicka  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 27
  • Joined: 19-February 11

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 09:46 PM

View Postmacosxnerd101, on 07 March 2011 - 09:44 PM, said:

Really though, you shouldn't be modifying a JComponent's size unless it is either a top-level container or you have very good reason and know what you are doing.


Which I don't. :)

Is there anyway I can center things, like JLabels in the grids, or is that a bad thing to do as well?
Was This Post Helpful? 0
  • +
  • -

#15 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10186
  • View blog
  • Posts: 37,613
  • Joined: 27-December 08

Re: Problem with object having a value different to what the constructor s

Posted 07 March 2011 - 09:49 PM

GridLayout doesn't allow a lot of freedom for that. Are you talking about centering the JLabels in the cells? If so, JPanel's LayoutManager by default is FlowLayout, which by default will center a JComponent horizontally.

In my experiences, a combination of BoxLayout, FlowLayout, GridLayout, and BorderLayout have been sufficient. You should look into these LayoutManagers as well.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2