Java - adding to an inherited JOptionPane - java

Good evening all!
I think there's something I don't understand here about either inheritance or JOptionPane, but basically I want to figure out how to actually use a new JOptionPane in the LuxuryCarRental subclass.
Currently it displays 2 dialog boxes if the choice is "l", one box from the parent class and a new one I added in the subclass. Ideally I would want only one dialog box. I think this is something that I can do without JOptionPane but I would like to try to make it work with JOptionPane if possible.
My code:
CarRental.java (parent class)
import javax.swing.JOptionPane;
public class CarRental
{
private String name;
private String zipCode;
private String size;
private double dailyFee;
private int rentalDays;
private double totalFee;
public CarRental(String name, String zipCode, String size, int rentalDays)
{
this.name = name;
this.zipCode = zipCode;
this.size = size;
if (size.equals("e"))
{
dailyFee = 29.99;
}
else if (size.equals("m"))
{
dailyFee = 38.99;
}
else if (size.equals("f"))
{
dailyFee = 43.50;
}
this.rentalDays = rentalDays;
totalFee = dailyFee * rentalDays;
}
public void display()
{
JOptionPane.showMessageDialog(null, "Car for " + name + " from zip code " + zipCode + "\n"
+ "Type = " + size + "\n"
+ "Daily Fee = " + dailyFee + "\n"
+ "Days = " + rentalDays + "\n"
+ "Your rental is $" + totalFee);
}
//includes getters and setters but I didn't include this in this post
LuxuryCarRental.java (subclass)
import javax.swing.JOptionPane;
public class LuxuryCarRental extends CarRental
{
public LuxuryCarRental(String name, String zipCode, String size, int rentalDays)
{
super(name, zipCode, size, rentalDays);
if (size.equals("l"))
{
this.setDailyFee(79.99);
String includeChauffeur;
includeChauffeur = JOptionPane.showInputDialog(null, "Include chauffeur? Y/N");
if (includeChauffeur.equals("Y") || includeChauffeur.equals("y"))
{
this.setDailyFee(279.99);
this.setTotalFee(this.getDailyFee()*this.getRentalDays());
JOptionPane.showMessageDialog(null, "Chauffeur # $200/day = $" + 200 * this.getRentalDays());
}
}
}
}
UserCarRental.java (driver class)
import javax.swing.JOptionPane;
public class UseCarRental
{
public static void main(String[] args)
{
String name = JOptionPane.showInputDialog("Enter name");
String zip = JOptionPane.showInputDialog("Enter zip code");
String size = JOptionPane.showInputDialog("Enter type of car" + "\n" + "e - economy" + "\n" + "m - midsize" + "\n" + "f - full" + "\n" + "l - luxury");
int days = Integer.parseInt(JOptionPane.showInputDialog("Enter days to rent"));
CarRental userInfo = new LuxuryCarRental(name, zip, size, days);
userInfo.display();
}
}
Any help would be greatly appreciated!

I think that the lesson here is to not mix UI code with model code. Understand that your CarRental class and all of its subclasses are logical or model classes, and can be thought of here as classes that model a physical or logical reality. They should be used in this capacity, and should be written so information can be passed into them and extracted out of them, but they should not interact directly with the user. Instead that is the responsibility of the UI (user interface) classes, of which here it is quite simple and only your main method. So I suggest that you get your JOptionPane calls out of both CarRental and LuxeryCarRental, and instead display the JOptionPane in your main method after extracting state from your CarRental object.
Otherwise, if you absolutely must have the model classes display their information, then do it in a method that can be fully overridden. In fact you would have your child class override the display() method, and then print out its data there.

Related

Different values for each subclass

I would like to create a school(Houses) with 4 subclasses that take a basic values from the superclass(color, logo etc, each subclass with different values) and keep track, each sub class to itself of the number of students and points.
I also want to grant the ability to add points only for instance of Houses directly.
This is the code:
public class Houses {
int students = 75;
String color;
String logo;
String Founder;
String Trait;
String name;
int points = 0;
protected void Welcome() {
System.out.println("Welcome to " + name + "! \n This house was founded by " +
Founder + " and his core value is " + Trait + " , the house logo is " + logo
+ " and his color is " + color + "\n We have right now " + students + " students and "
+ points + " points. BEST OF LUCK!");
}
public void AddPoints(int x){
points += x;
System.out.println(x + " Points added!\nYour house now have " + points + " points");
}}
public class Gryffindor extends Houses {
Gryffindor() {
name = "Gryffindor";
students += 1;
color = "Red";
logo = "Lion";
Founder = "Godric Gryffindor";
Trait = "Brave";
Welcome();
}}
if im making the students and point as static its working fine but of course it add up all the sub classes together.
the best idea is to declare the values students and points inside each subclass as static?
Thanks for your time!
Looks like a misuse of sub-classes. Unless each sub-class is going to have it's own unique functionality, then each set of data should be associated to an instance of a House. You'd then most likely want to use the Constructor to set this data.
House Class
public class House {
int students;
String name;
String color;
//Other class variables
public House(int students, String name, String color) {
this.students = students;
this.name = name;
this.color = color;
}
//Various methods
}
Main Class
public class HouseTest {
public static void main(String[] args) {
House gryffindor = new House(75, "Gryffindor", "Red");
House ravenclaw = new House(68, "Ravenclaw", "Blue");
}
}
However, if you really want to set this data using a sub-class you can make use of the House constuctor via the super keyword which calls the parent constructor. Using the House from my code above it would be:
Gryffindor Class
public class Gryffindor extends House {
public Gryffindor() {
super(75, "Gryffindor", "Red");
//Set value for anything unique to Gryffindor here after super keyword
}
//Gryffindor specific methods
}
I will use a singleton School class to keep a single state count of students and points throughout the program. So create a class with those values you want to keep a single state track of and make them the class fields.
A singleton is a class that is instantiated once in memory and have the object shared by all classes within the application. This single state object in memory hold single state data points.
public class School{
private int students = 75;
private int points = 0;
private static final School instance = new School();
private School() {}
public static School getInstance() { return instance; }
public synchronized void addStudent() {
students++;
}
public synchronized void addPoints(int x) {
points += x;
}
public synchronized int getStudents() { return students; }
public synchronized int getPoints() { return points; }
}
So your House class will look like:
public class Houses {
School school = School.getInstance();
int students = school.getStudents();
String color;
String logo;
String Founder;
String Trait;
String name;
int points = school.getPoints();
protected void Welcome() {
System.out.println("Welcome to " + name + "! \n This house was founded by " +
Founder + " and his core value is " + Trait + " , the house logo is " + logo
+ " and his color is " + color + "\n We have right now " + students + " students and "
+ points + " points. BEST OF LUCK!");
}
public void AddPoints(int x){
school.addPoints(x);
System.out.println(x + " Points added!\nYour house now have " + points + " points");
}}
And your Gryffindor class
public class Gryffindor extends Houses {
Gryffindor() {
name = "Gryffindor";
school.addStudent();
color = "Red";
logo = "Lion";
Founder = "Godric Gryffindor";
Trait = "Brave";
Welcome();
}}

Java toString in class

I am getting an error of cannot find symbol in my code posted below. I am trying to initalise a sedan using it's class and have the toString function right after but nothing is working for me. Please help
class cars {
String make;
String model;
String color;
int year;
double price;
public String sedancClass(String initMake, String initModel, String initColor, int initYear, double initPrice) {
make = initMake;
model = initModel;
color = initColor;
year = initYear;
price = initPrice;
String name = "Sedan";
String main = (color + " " + make + " " + model + " " + name + " " + year + " costs $" + price);
return main;
}
}
public class autoPark {
public static void main(String args[]) {
cars sedan1;
sedan1 = new sedanClass("Ford" , "Model-1" , "white" , 2015, 20000);
}
}
According to what you provided, I think this is what you are trying to do
class cars {
String make;
String model;
String color;
int year;
double price;
// parametised constructor
public cars (String initMake, String initModel, String initColor, int initYear, double initPrice) {
make = initMake;
model = initModel;
color = initColor;
year = initYear;
price = initPrice;
}
#Override
public String toString() {
String name = "Sedan";
String main = (color + " " + make + " " + model + " " + name + " " + year + " costs $" + price);
return main;
}
}
public class autoPark {
public static void main(String args[]) {
cars sedan1; // declaring cars object by name sedan1
sedan1 = new cars("Ford" , "Model-1" , "white" , 2015, 20000); // initialising sedan1 using cars constructor
System.out.println(sedan1); // printing sedan1 for invoking toString() method
}
}
Why we use #Override annotation source
Using #Override annotation while overriding a method is considered as a best practice for coding in java because of the following two advantages:
If programmer makes any mistake such as wrong method name, wrong parameter types while overriding, you would get a compile time error. As by using this annotation you instruct compiler that you are overriding this method. If you don’t use the annotation then the sub class method would behave as a new method (not the overriding method) in sub class.
It improves the readability of the code. So if you change the signature of overridden method then all the sub classes that overrides the particular method would throw a compilation error, which would eventually help you to change the signature in the sub classes. If you have lots of classes in your application then this annotation would really help you to identify the classes that require changes when you change the signature of a method.

How Do I Get Customer Input To Display?

I am in an Object-Oriented Programming course in college and I have to use Java to start a program that will eventually incorporate a full on GUI by the end of the course. For the beginning of this project, I have to basically use message boxes to set up how a customer would order a sub to be delivered to their home.
Here's what I have so far:
This is the main class
import javax.swing.*;
//Here is the main class
public class Subs {
public static void main(String[] args) {
// Begin Main Method
char letter;
String input;
String input1, input2, input3, input4, input6, input8;
int input5, input7;
int subL; //length of sub in inches
int cup; //size of drink in ounces
JFrame frame = new JFrame("Message");
JOptionPane.showMessageDialog(frame, "Welcome to Famous Subs! ");
input1 = JOptionPane.showInputDialog(frame, "Please Enter Your Name: ");
input2 = JOptionPane.showInputDialog(frame, "Please Enter Your Address: ");
do {
input3 = JOptionPane.showInputDialog(frame, "What kind of sub would "
+ "you like? " +
"\n Turkey Club" +
"\n Philly" +
"\n Meatball" +
"\n Chicken Parm");
input4 = JOptionPane.showInputDialog(frame, "What type of bread? " +
"\n White" +
"\n Wheat" +
"\n Rosemary" +
"\n Italian Herb");
subL = getValidLength();
input6 = JOptionPane.showInputDialog(frame, "What would you like to "
+ "to drink? " +
"\n Water" +
"\n Soda" +
"\n Juice");
cup = getValidCup ();
input8 = JOptionPane.showInputDialog(frame, "Do you wish to continue?\n "+
"'y' or 'Y' for YES\n"+
"'n' or 'N' for NO\n");
Order firstOrder = new Order(input1, input2, input3, input4, input6, subL, cup);
JOptionPane.showMessageDialog(frame, firstOrder.toString());
letter = input1.charAt(0);
}
while (letter == 'Y'|| letter == 'y');
System.exit(0);
}
private static int getValidLength()
{
int s;
String input5;
do{
input5 = JOptionPane.showInputDialog(null, "What size of sub do you wish "
+ "to order? "+
"\n 6 inch"+
"\n 12 inch");
s = Integer.parseInt(input5);
} while (!(s==6 || s==12));
return s;
}
private static int getValidCup()
{
int c;
String input8;
do{
input8 = JOptionPane.showInputDialog(null, "What size drink? " +
"\n Small 12oz." +
"\n Medium 24oz." +
"\n Large 36oz.");
c = Integer.parseInt(input8);
}
while (!(c==12 || c==24 || c==36));
return c;
}
}
This is my subclass
//This is the class for the order
public class Order {
//creating my variables
private String Customer;
private String Address;
private String name;
private String bread;
private String drink;
private int length; //in inches
private int size; //in ounces
private double SubPrice;
private double DrinkPrice;
private double total;
//blank constructor
public Order(){}
//Create a constructor to hold variables
public Order (String Customer, String Address, String name, String bread, String drink, int subL, int cup){
this.Customer = Customer;
this.Address = Address;
this.name = name;
this.bread = bread;
this.drink = drink;
subL = length;
cup = size;
}
//create the getters and setters for the variables
public String getCustomer(){
return Customer;
}
public void setCustomer(String Customer){
this.Customer = Customer;
}
public String getAddress(){
return Address;
}
public void setAddress(String Address){
this.Address = Address;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getBread(){
return bread;
}
public void setBread(String bread){
this.bread = bread;
}
public String getDrink(){
return drink;
}
public void setDrink(String drink){
this.drink = drink;
}
public int getLength(){
return length;
}
public void setLength (int length){
this.length = length;
}
public int getSize(){
return size;
}
public void setSize (int size){
this.size = size;
}
public void setSubPrice (int subL, double SubPrice){
if (subL == 6)
SubPrice = 7.95;
else if (subL == 12)
SubPrice = 12.75;
}
public void setDrinkPrice(int cup, double DrinkPrice){
if (cup == 12)
DrinkPrice = 2.00;
else if (cup == 24)
DrinkPrice = 4.00;
else if (cup == 36);
DrinkPrice = 6.00;
}
public void setTotal(){
total = SubPrice + DrinkPrice;
}
#Override
public String toString(){
String grandOrder = "Greetings " + Customer +
"\nHere is your order: " +
"\n" + name +
"\n" + bread +
"\n" + drink +
"\nThe length of your sub is: " + length +
"\nThe size of your drink is: " + size +
"\nThe Price for your sub is: " + SubPrice +
"\nThe Price for your drink is: " + DrinkPrice +
"\nHere is your total: $" + calculateTotal(DrinkPrice, SubPrice) +
"\nThis will be delivered to: " + Address;
return grandOrder;
}
}
Everything runs just fine except the fact that the last box to show up returns all the string fields as null and the int and double variables as 0 or 0.0.
How do I return the values for what the user inputs on each dialog box? In addition, how do I get he customer's name and address to appear on this final screen? Thanks.
You never initialize fields of your Order. You call constructor without parameters public Order(){}. So you see the default values of the fields.
What you should do:
Be sure that you keep in a variable the value for the name of the client. (input = JOptionPane.showInputDialog(frame, "Please Enter Your Name: ");)
Be sure that you keep in variable user's input after "input = JOptionPane.showInputDialog(frame, "What kind of sub would "
+ "you like? " ...".
After get all inputs from the user, create Order object passing user's values
Order firstOrder = new Order(name, bread,drink,int subL, cup);
Change the constructor with parameters like that:
public Order (String name, String bread, String drink, int subL, int cup). You should not pass subPrice and drinkPrice because you Order class already know these values (see setdrinkPrice()). You determine the price of a cup based on the int cup. BTW, can you change the name of the method? Something like setDrinkPrice().
You never call setDrinkPrice() and setsubPrice()(should be setSubPrice(). You can do this when you calculate the total.
Start with these changes and if you have more problems ask .
Okay, a few things are going on here.
Order firstOrder;
firstOrder = new Order();
Can just be written as
Order firstOrder = new Order();
there's no need to do that on two lines. But, more importantly, you've not giving it any parameters, so Java is linking that to the empty constructor (the one that doesn't assign anything.) All of that nice constructor code you have isn't getting called.
To do that, you need to actually do something with those input fields you keep assigning (at the moment you're just ignoring them and writing over them); specifically, you should store them in local variables, and then pass them to the constructor like:
firstOrder = new Order(arg1, arg2, ...)
Also, Order isn't a subclass; it isn't extending anything. (Except Object, but we don't generally call something a subclass just for that.
input = JOptionPane.showInputDialog(frame, "Please Enter Your Name: ");
input = JOptionPane.showInputDialog(frame, "Please Enter Your Address: ");
On the first line above, you get the customer's name. then you call the second line, throwing away the customer's name without saving it anywhere.

Is there any way to retrieve an input value from the past

I'm a beginner in java and it is my only code I know how to use so far. I'm working on a food system for an RPG game. Basically it displays a list of the available food items and ask you to press number to eat . After pressing a number, it prints out what you have decided to eat based on what your number corresponded to. I then need to retrieve what "food" you ate so that I can use it's stats. Here's what I have so far:
public String eatmenu() {
System.out.print ( "Consumables: ");
for ( Sustenance consum : consumables ) {
System.out.print ( "[" + consum + "], " );
}
int number = consumables.size();
int counter = 1;
while ( counter <= number ){
System.out.print ("\nPress " + counter + " to consume " + consumables.get(counter-1));
counter++;
}
int choice = reader.nextInt();
String eatchoice = "You decided to consume " + consumables.get(choice-1);
return eatchoice;
}
public String eat3(){
//the food just eaten,
}
Heres the code for the Food Class or "Sustenance":
public class Sustenance extends Item {
String n;
int v;
int s;
public Sustenance ( String name, int Nvalue, int size ){
n= name;
Nvalue = v;
size = s;
}
public String toString() {
String str = "The " + n + "increased your Nutrition level by " + v + ".\nYour backpack is also " +
s + " pounds lighter.";
return str;
}
}
Any ideas are appreciated as to what to put for the eat3 method. I know I will be using the toString method in order to print out the effects of eating the specific item but how do I refer to the item I just ate? I will take everything as critique. Thank you for your time.
Use JavaBeans to set the food and then get it. For example:
public class FoodBean{
public FoodBean(){}
private String foodName;
// other fields which you wana set or get
public void setFoodName(String foodName){
this.foodName = foodName;
}
public String getFoodName(){
return this.foodName;
}
// override the toString() if you want the object to represent the foodName stored
#Override
public String toString(){
return this.foodName;
}
}
Ok so now we have a BeanClass..
now you need to create a bean object whenever the user clicks any item
FoodBean fb = new FoodBean();
fb.setFoodName("get food name from the mapped list here against its number");
now use getFoodName() anywhere in the program, just be careful, the bean object above has local scope if you create it in a method, you need to make a same reference to FoodBean globally and assign the new created object to it, and then use that global reference anywhere in the class.
Further take a look at this simple tutorial

stackoverflow error in class constructor

Please excuse what is probably a very basic question, but I am writing a program to store employee info and it works fine until it tries to set the info inside my employee class. It gives a stackoverflow error and I cannot figure out why. Thanks for any help.
Main class:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner Input = new Scanner(System.in);
System.out.println("Enter the number of employees to enter.");
int employeeCount = Input.nextInt();
Input.nextLine();
Employee employee[] = new Employee[employeeCount];
String namesTemp;
String streetTemp;
String cityTemp;
String stateTemp;
String zipCodeTemp;
String address;
String dateOfHireTemp;
for(int x = 0; x < employeeCount; x++)
{
System.out.println("Please enter the name of Employee " + (x + 1));
namesTemp = Input.nextLine();
System.out.println("Please enter the street for Employee " + (x + 1));
streetTemp = Input.nextLine();
System.out.println("Please enter the city of Employee " + (x + 1));
cityTemp = Input.nextLine();
System.out.println("Please enter the state of Employee " + (x + 1));
stateTemp = Input.nextLine();
System.out.println("Please enter the zip code of Employee " + (x + 1));
zipCodeTemp = Input.nextLine();
address = streetTemp + ", " + cityTemp + ", " + stateTemp + ", " + zipCodeTemp;
System.out.println("Please enter the date of hire for Employee " + (x + 1));
dateOfHireTemp = Input.nextLine();
System.out.println("The employee ID for employee " + (x + 1) + " is " + (x + 1));
employee[x] = new Employee(x, namesTemp, address, dateOfHireTemp);
}
}
}
Employee class:
public class Employee
{
private int employeeID;
private Name name;
private Address address;
private DateOfHire hireDate;
public Employee()
{
}
public Employee(int employeeID, String name, String address, String hireDate)
{
String temp;
Name employeeName = new Name(name);
this.employeeID = employeeID;
}
}
Name class:
public class Name
{
public Name name;
public Name(String name)
{
Name employeeName = new Name(name);
this.name = employeeName;
}
}
The most common cause of StackoverflowExceptions is to unknowingly have recursion, and is that happening here? ...
public Name(String name)
{
Name employeeName = new Name(name); // **** YIKES!! ***
this.name = employeeName;
}
Bingo: recursion!
This constructor will create a new Name object whose constructor will create a new Name object whose constructor will... and thus you will keep creating new Name objects ad infinitum or until stack memory runs out. Solution: don't do this. Assign name to a String:
class Name {
String name; // ***** String field!
public Name(String name)
{
this.name = name; // this.name is a String field
}
Typically a class is used to group data together with functionality. It appears that the Name class is simply a wrapper for a String without adding any functionality. At this point in your Java career, it is probably better to declare String name; in the Employee class and remove the Name class all together. (Note that this would remove the error from your code that Hovercraft Full of Eels described.)

Categories

Resources