Public method to move 3 objects but keep them aligned - java

I am trying to write a public instance method names move()
It takes two integer arguments which showing the amount that the objects needs to change the values of xPos and yPos.
I don't want the method the return a value.
I have done this below but I get the following error message?
Compilation failed (18/01/2020 15:16:31)
Error: line 1 - method move in class StickFigure cannot be applied to given types;
required: no arguments
found: int,int
reason: actual and formal argument lists differ in length
Could I get some guidance where I am going wrong.
/*Instance variables*/
private int xPos;
private int yPos;
private Circle head;
private Triangle body;
private Rectangle leg;
public person()
{
super();
this.head = new Circle(30, OUColour.PINK);
this.body = new Triangle (50, 50, OUColour.RED);
this.leg = new Rectangle (6, 50, OUColour.PINK);
this.setXPos(25);
this.setYPos(220);
this.alignAll();
}
public void setXPos(int newPos)
{
this.xPos = newPos;
this.body.setXPos(newPos);//part (b)(iii)
}
public int getXPos()
{
return this.xPos;
}
public void setYPos(int newPos)
{
this.yPos = newPos;
this.body.setYPos(newPos);//part (b)(iii)
}
public int getYPos()
{
return this.yPos;
}
public Circle getHead()
{
return this.head;
}
public Triangle getBody()
{
return this.body;
}
public Rectangle getLeg()
{
return this.leg;
}
public void alignHead()
{
this.head.setXPos(this.body.getXPos() + (this.body.getWidth() - this.head.getDiameter())/2);
this.head.setYPos(this.body.getYPos() - this.head.getDiameter());
}
public void alignBody()
{
this.body.setXPos(25);
this.body.setYPos(220);
}
public void alignLeg()
{
this.leg.setXPos(this.body.getXPos() + (this.body.getWidth() - this.leg.getWidth())/2);
this.leg.setYPos(this.body.getYPos() + this.leg.getHeight());
}
public void alignAll()
{
this.alignBody();
this.alignHead();
this.alignLeg();
}
public void move(int newxPos, int newyPos)
{
this.body.setXPos(xPos + newxPos);
this.body.setYPos(yPos + newyPos);
this.alignAll();
this.delay(20);
}

If you want method move to take arguments, you have to declare it:
public void move(int xPos, int yPos)
instead of
public void move()

Related

Custom Classes: Custom type cannot be converted to other custom type

I have been given an assignment with two given classes, one abstract parent class Lot.java, and test class TestLots.java. I am not supposed to edit either of these. The assignment is to create two subclasses of Lot so that the errors in TestLots are no longer errors.
The purpose of the program is to display the name and area of the lots in order of are like this:
Lot ID L3 has area: 13500.0
Lot ID L2 has area: 27000.0
Lot ID L1 has area: 35000.0
Lot ID L4 has area: 70000.0
However I get the errors:
Incompatible types: LotType1 cannot be converted to Lot, and
LotType2 cannot be converted to Lot. I suspect the issue is in my subclass and the way it is supposed to override or reference the parent class.
Here is TestLots, where I get the error:
public class TestLots {
public static void main(String args[]){
// an array of lots -- some of type1, some of type2
Lot[] lots = {new LotType1("L1",350, 200), // error here
new LotType2("L2",100,270),
new LotType1("L3",100, 270),
new LotType2("L4",350,200)
};
// sort the lots of mixed types by area (note, you'll have to implement
// Comparable interface correctly in LotType1 and LotType2 for this to work:
java.util.Arrays.sort(lots);
// print out sorted results
for (Lot lot: lots) {
System.out.print(lot + " ");
System.out.println();
}
}
}
Here is Lot, the parent class
public abstract class Lot {
public abstract double calculateArea();
public abstract String getID();
#Override
public String toString() {
return "Lot ID "+ getID() +" has area: "+ calculateArea();
}
}
The subclasses are nearly identical:
public class LotType1 extends Lot implements Comparable<LotType1>{
String name;
int height;
int width;
double area;
public LotType1(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height)/2);
}
#Override
public int compareTo(LotType1 lot) {
area = ((width * height)/2);
if(area==lot.area)
{
return 0;
}
else if(area>lot.area)
{
return 1;
}
else
{
return -1;
}
}
}
Edit to add LotType2:
public class LotType2 extends Lot implements Comparable<LotType2>{
String name;
int height;
int width;
double area;
public LotType2(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = (width * height);
}
#Override
public int compareTo(LotType2 lot) {
area = (width * height);
if(area==lot.area)
{
return 0;
}
else if(area>lot.area)
{
return 1;
}
else
{
return -1;
}
}
}
Sorry this post is so long. I decided to include all of the relevant files in case that helps.
The problem is that you can't sort objects with different comparable implementations in the same collection. Change the subclass to implement Comparable of Lot :
public class LotType1 extends Lot implements Comparable<Lot> {
and also use calculateArea() in the compareTo method:
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
Your full version of code is given below.
It will give you the expected result.
public class TestLots {
public static void main(String args[]) {
// an array of lots -- some of type1, some of type2
Lot[] lots = {new LotType1("L1", 350, 200), // error here
new LotType2("L2", 100, 270),
new LotType1("L3", 100, 270),
new LotType2("L4", 350, 200)
};
// sort the lots of mixed types by area (note, you'll have to implement
// Comparable interface correctly in LotType1 and LotType2 for this to work:
java.util.Arrays.sort(lots);
// print out sorted results
for (Lot lot : lots) {
System.out.print(lot + " ");
System.out.println();
}
}
}
abstract class Lot {
public abstract double calculateArea();
public abstract String getID();
#Override
public String toString() {
return "Lot ID " + getID() + " has area: " + calculateArea();
}
}
class LotType1 extends Lot implements Comparable<Lot> {
String name;
int height;
int width;
double area;
public LotType1(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height) / 2);
}
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
}
class LotType2 extends Lot implements Comparable<Lot> {
String name;
int height;
int width;
double area;
public LotType2(String name, int height, int width) {
this.name = name;
this.height = height;
this.width = width;
}
public String getID() {
return name;
}
public double calculateArea() {
return area = ((width * height) / 2);
}
#Override
public int compareTo(Lot lot) {
if (calculateArea() == lot.calculateArea()) {
return 0;
} else if (calculateArea() > lot.calculateArea()) {
return 1;
} else {
return -1;
}
}
}

Java Custom Event Handling

Good Day,
I am writing a custom event handler in Java. I have a class called BoogieCarMain.java that instantiates three instances of a type called BoogieCar. Whenever any of the three instances exceeds a certain speed limit, then an event should be fired off. The code I currently have is working, so here is what I have:
// BoogieCar.java
import java.util.ArrayList;
public class BoogieCar {
private boolean isSpeeding = false;
private int maxSpeed;
private int currentSpeed;
private String color;
BoogieSpeedListener defaultListener;
public BoogieCar(int max, int cur, String color) {
this.maxSpeed = max;
this.currentSpeed = cur;
this.color = color;
}
public synchronized void addSpeedListener(BoogieSpeedListener listener) {
defaultListener = listener;
}
public void speedUp(int increment) {
currentSpeed += increment;
if (currentSpeed > maxSpeed) {
processSpeedEvent(new BoogieSpeedEvent(maxSpeed, currentSpeed, color));
isSpeeding = true;
} else {
isSpeeding = false;
}
}
public boolean getSpeedingStatus() {
return isSpeeding;
}
private void processSpeedEvent(BoogieSpeedEvent speedEvent) {
defaultListener.speedExceeded(speedEvent);
}
}
// BoogieCarMain.java
import java.util.ArrayList;
public class BoogieCarMain {
public static void main(String[] args) {
BoogieCar myCar = new BoogieCar(60, 50, "green");
BoogieCar myCar2 = new BoogieCar(75, 60, "blue");
BoogieCar myCar3 = new BoogieCar(65, 25, "pink");
BoogieSpeedListener listener = new MySpeedListener();
myCar.addSpeedListener(listener);
myCar2.addSpeedListener(listener);
myCar3.addSpeedListener(listener);
myCar.speedUp(50); // fires SpeedEvent
System.out.println(myCar.getSpeedingStatus());
myCar2.speedUp(20);
System.out.println(myCar2.getSpeedingStatus());
myCar3.speedUp(39);
System.out.println(myCar3.getSpeedingStatus());
}
}
// BoogieSpeedListener.java
public interface BoogieSpeedListener { // extends java.util.EventListener
public void speedExceeded(BoogieSpeedEvent e);
}
// MySpeedListener.java
public class MySpeedListener implements BoogieSpeedListener {
#Override
public void speedExceeded(BoogieSpeedEvent e) {
if (e.getCurrentSpeed() > e.getMaxSpeed()) {
System.out.println("Alert! The " + e.getColor() + " car exceeded the max speed: " + e.getMaxSpeed() + " MPH.");
}
}
}
// BoogieSpeedEvent.java
public class BoogieSpeedEvent { // extends java.util.EventObject
private int maxSpeed;
private int currentSpeed;
private String color;
public BoogieSpeedEvent(int maxSpeed, int currentSpeed, String color) {
// public SpeedEvent(Object source, int maxSpeed, int minSpeed, int currentSpeed) {
// super(source);
this.maxSpeed = maxSpeed;
this.currentSpeed = currentSpeed;
this.color = color;
}
public int getMaxSpeed() {
return maxSpeed;
}
public int getCurrentSpeed() {
return currentSpeed;
}
public String getColor() {
return color;
}
}
My question is: While this code works, I would like the BoogieCar type to notify BoogieCarMain directly without me have to "poll" the BoogieCar type by having to invoke the getSpeedingStatus() method.
In other words, perhaps defining a variable in BoogieCarMain.java that changes whenever one of the three cars exceeds its predefined speed limit. Is it possible to have the BoogieCar type set the variable?
Is there a cleaner way to do this?
TIA,
coson
Callbacks are ideal for this scenario.
// BoogieCarMain provides a sink for event-related information
public void handleSpeeding(BoogieCar car) {
System.out.println(car.getSpeedingStatus());
}
// MySpeedListener knows about an object that wants event-related information.
// I've used the constructor but an addEventSink method or similar is probably better.
public MySpeedListener(BoogieCarMain eventSink) {
this.eventSink = eventSink;
}
// MySpeedListener handles events, including informing objects that want related information.
// You decide if the event is an appropriate type for the sink to know about.
// Often it isn't, and instead your listener should pull the relevant info out of the event and pass it to the sink.
public void speedExceeded(BoogieSpeedEvent e) {
if (e.getCurrentSpeed() > e.getMaxSpeed()) {
// I've taken the liberty of adding the event source as a member of the event.
eventSink.handleSpeeding(e.getCar());
}
}

How to set class invariants without using conditional if statements

I have a class called pixel. I am making a constructor which takes in the red,green,blue,alpha values of a single pixel. How can I have it so that the program only take in valid values for these (e.g. 0 to 255) without using if statements?
Here is my class below:
public class Pixel {
public int redPix;
public int bluePix;
public int greenPix;
public int alpha;
public Pixel(int redPix , int bluePix , int greenPix , int alpha) {
this.redPix = redPix;
this.bluePix = bluePix;
this.greenPix = greenPix;
this.alpha = alpha;
}
public void setRed(int redPix) {
this.redPix = redPix;
}
public int getRed() {
return(redPix);
}
public void setBlue(int bluePix) {
this.bluePix = bluePix;
}
public int getBlue() {
return(bluePix);
}
public void setGreen(int greenPix) {
this.greenPix = greenPix;
}
public int getGreen() {
return(greenPix);
}
public void setAlpha(int alpha) {
this.alpha = alpha;
}
public int getAlpha() {
return(alpha);
}
public static void main(String[] args){
}
}
You can use assertions to specify class invariants. It is actually recommended for private methods.
assert x >= 0 && x <= 255;
Likely, best you can do is to write method-helper like this:
private void checkArg(int arg) {
if (arg < 0 || arg > 255) {
throw new IllegalArgumentException("Wrong argument: " + arg);
}
}
And then use it in the beginning of all your methods.

Cannot Find Symbol Method Error

I have an assignment from my Java 1 class (I'm a beginner) and the question instructs us to make some code more object-oriented. I've done what I can for the assignment, but one of my files consistently gives me a Cannot Find Symbol Method error even though the files are in the same project. I know the methods are there, so what's going on? The error only occurs in AlienPack, which doesn't seem to recognize the other files, all of which are in the same project (including AlienPack). The getDamage() method that's being called in AlienPack isn't being found (it's in SnakeAlien, OgreAlien, etc).
EDIT: The new error for the getDamage() methods I'm trying to invoke in AlienPack is that the methods still aren't being found. AlienDriver can't find calculateDamage() either.
Here's the code I've got so far:
Alien:
public class Alien {
// instance variables
private String name;
private int health;
// setters
public void setName(String n) {
name = n; }
public void setHealth(int h) {
if(h>0&&h<=100) {
health = h;
} else {
System.out.println("Error! Invalid health value!");
System.exit(0); } }
// getters
public String getName() {
return name; }
public int getHealth() {
return health; }
// constructors
public Alien() {
setName("No name");
setHealth(100); }
public Alien(String n, int h) {
setName(n);
setHealth(h); }
public Alien(Alien anAlien) {
setName(anAlien.getName());
setHealth(anAlien.getHealth()); }
public Alien clone() {
return new Alien(this);
} }
SnakeAlien:
public class SnakeAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public SnakeAlien() {
super();
setDamage(0); }
public SnakeAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public SnakeAlien(SnakeAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public SnakeAlien clone() {
return new SnakeAlien(this);
} }
OgreAlien:
public class OgreAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public OgreAlien() {
super();
setDamage(0); }
public OgreAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public OgreAlien(OgreAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public OgreAlien clone() {
return new OgreAlien(this);
} }
MarshmallwManAlien:
public class MarshmallowManAlien extends Alien { // new file
// instance variables
private int damage;
// setters
public void setDamage(int d) {
if(d>0) {
damage = d;
} else {
System.out.println("Error! Invalid damage value!");
System.exit(0); } }
// getters
public int getDamage() {
return damage; }
// constructors
public MarshmallowManAlien() {
super();
setDamage(0); }
public MarshmallowManAlien(String n, int h, int d) {
super(n, h);
setDamage(d); }
public MarshmallowManAlien(MarshmallowManAlien anAlien) {
super(anAlien);
setDamage(anAlien.getDamage()); }
public MarshmallowManAlien clone() {
return new MarshmallowManAlien(this);
} }
AlienPack:
public class AlienPack { // new file, this one isn't recognizing the others
// instance variables
private Alien[] pack;
// setters
public void setPack(Alien[] aliens) {
pack = new Alien[aliens.length];
for(int i = 0; i<aliens.length; i++) {
pack[i]=aliens[i].clone(); } }
// getters
public Alien[] getPack() {
Alien[] temp = new Alien[pack.length];
for(int i = 0; i<pack.length; i++) {
temp[i]=pack[i].clone(); }
return temp; }
// constructors
public AlienPack() {
Alien[] nothing = new Alien[1];
nothing[0]=null;
setPack(nothing); }
public AlienPack(Alien[] aliens) {
setPack(aliens);}
// other methods
public int calculateDamage() {
int damage = 0;
for(int i = 0; i<pack.length; i++) {
if((new SnakeAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else if((new OgreAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else if((new MarshmallowManAlien()).getClass()==pack[i].getClass()) {
pack[i].getDamage() +=damage;
} else {
System.out.println("Error! Invalid object!");
System.exit(0); } }
return damage; } }
AlienDriver:
public class AlienDriver { // driver class
public static void main(String[] args) {
Alien[] group = new Alien[5];
group[0]= new SnakeAlien("Bobby", 100, 10);
group[1]= new OgreAlien("Timmy", 100, 6);
group[2]= new MarshmallowManAlien("Tommy", 100, 1);
group[3]= new OgreAlien("Ricky", 100, 6);
group[4]= new SnakeAlien("Mike", 100, 10);
System.out.println(group.calculateDamage());
} }
Two problems:
pack[i].getClass().getDamage() ...
should be just
pack[i].getDamage() ...
You seem to be confused about what the getClass() method does. It returns an object which represents the class (i.e. java.lang.Class) of another object. It is used for reflection. To invoke getDamage() you would just invoke it directly on pack[i] as shown above.
However...
You are attempting to invoke the method getDamage() using a reference of type Alien, which is a base class of all the concrete alien types. If you want to do it that way,
getDamage() needs to be declared abstract in the base class so it can be found and dispatched to the correct subclass when invoking it via an Alien reference.
In Alien:
public abstract class Alien {
...
public abstract int getDamage();
An alternative is to cast to the appropriate subclass at each point since you know what it is:
((SnakeAlien)pack[i]).getDamage() +=damage;
However (again) even that is wrong. You can't apply += to an "rvalue". What you need to do here is either:
Also declare setDamage() abstract in Alien and do pack[i].setDamage(pack[i].getDamage()+damage);
If casting, ((SnakeAlien)pack[i]).setDamage( ((SnakeAlien)pack[i].getDamage()) + damage);
My Recommendation:
In class Alien:
public abstract class Alien {
...
private int damage = 0; // Move damage up to the abstract base class
public int addToDamage(int n) { this.damage += n; }
...
}
In your driver, no need to test the class. Invoke the addToDamage() method on the Alien reference.
I think that at least part of your problem is the getClass() method. You are expecting it to return an object but it does not. Just call directly to the array.
pack[I].getDamage()
should work assuming that the correct type of object is stored in pack()

Netbeans warning: Exporting non-public type through public API [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I'm creating a Slick2D game. Right now, I'm creating a Video class, which contains inner classes (FrameSize, FPS, FullScreen..). So I had an OOD idea to crate in way, like we call System.out.println(). That means that I will have public Video class and public static instances of his inner clasess, but netbeans IDE throws me a hint with "Exporting non-public type through public API ". So, should I just ignore that and keep doing the way I was doing or it would be great if you could suggest me your idea?
VIDEO
public class Video {
public static FrameSize frameSize;
public static FullScreen fullScreen;
public static FPS fps;
private Video() {}
public static void loadArguments(Scanner loadInput) {
boolean isVideo = false;
String readLine;
while (loadInput.hasNext()) {
readLine = loadInput.next();
if (readLine.equalsIgnoreCase("video")) {
isVideo = true;
break;
}
}
while (isVideo && loadInput.hasNext()) {
readLine = loadInput.next();
if (readLine.equalsIgnoreCase("end")) {
break;
}
String[] line = readLine.split("=");
String key = line[0];
String value = line[1];
switch (key) {
case "width":
frameSize.setWidth(Integer.parseInt(value));
break;
case "height":
frameSize.setHeight(Integer.parseInt(value));
break;
case "fullscreen":
break;
case "fps":
break;
default:
System.err.println("Unknown video key: " + key);
break;
}
}
}
public static void saveArguments(String filePath) {
Scanner saveInput;
try {
saveInput = new Scanner(new File(filePath));
} catch (FileNotFoundException fne) {
System.err.println("Invalid settings-file.");
return;
}
// TO DO: save function
saveInput.close();
}
class FrameSize {
public final int[][] SIZE_VALUES = {
{800, 600},
{1000, 700},
{1200, 800},
{1400, 900}
};
private int index;
private int width, height;
private FrameSize() {}
public void setSize(int width, int height) {
this.width = width;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
#Override
public String toString() {
return this.width + " x " + this.height;
}
}
class FullScreen {
private boolean fullScreen;
private FullScreen() {}
public boolean isFullScreen() {
return fullScreen;
}
public void setFullScreen(boolean fullScreen) {
this.fullScreen = fullScreen;
}
#Override
public String toString() {
return "" + fullScreen;
}
}
class FPS {
private boolean FPS;
private FPS() {}
public boolean isFPS() {
return FPS;
}
public void setFPS(boolean FPS) {
this.FPS = FPS;
}
#Override
public String toString() {
return "" + fps;
}
}
}
AUDIO
public class Audio {
private static Sound sound;
private static Volume volume;
private Audio() {}
public void loadArguments(Scanner loadInput) {
boolean isAudio = false;
String readLine;
while (loadInput.hasNext()) {
readLine = loadInput.next();
if (readLine.equalsIgnoreCase("audio")) {
isAudio = true;
break;
}
}
while (isAudio && loadInput.hasNext()) {
readLine = loadInput.next();
if (readLine.equalsIgnoreCase("end")) {
break;
}
String[] line = readLine.split("=");
String key = line[0];
String value = line[1];
switch (key) {
case "sound":
break;
case "volume":
break;
default:
System.err.println("Unknown audio key: " + key);
break;
}
}
}
public void saveArguments(String filePath) {
Scanner saveInput;
try {
saveInput = new Scanner(new File(filePath));
} catch (FileNotFoundException fne) {
System.err.println("Invalid settings-file.");
return;
}
// TO DO: save function
saveInput.close();
}
class Sound {
private boolean sound;
private Sound() {}
public boolean isSound() {
return sound;
}
public void setSound(boolean sound) {
this.sound = sound;
}
#Override
public String toString() {
return "" + sound;
}
}
class Volume {
private static final double PITCH = 0.1d;
private double volume;
private Volume() {}
public double getVolume() {
return volume;
}
public void setVolume(double volume) {
this.volume = volume;
}
public void increaseVolume() {
if (!isVolumeRange(this.volume)) {
return;
}
this.volume = this.volume + PITCH;
}
public void decreaseVolume() {
if (!isVolumeRange(this.volume)) {
return;
}
this.volume = this.volume - PITCH;
}
public boolean isVolumeRange(double volume) {
return volume >= 0.0 && volume <= 10.0;
}
}
}
Video class contains a declaration of a public class variable frameSize of type FrameSize.
A public modifier means, that frameSize variable is visible to all.
package package1;
public class Video {
public static FrameSize frameSize;
}
// private class
class FrameSize {
}
However FrameSize is a local class - it is visible only to members of the same package. In the above example, only members of package package1 can see that class, and below code compiles fine:
package package1;
public class Test {
void test(){
FrameSize x = Video.frameSize;
}
}
however this code (different package) gives a compilation error:
package package2;
import package1.*;
public class Test {
void test(){
// this line won't compile - FrameSize class is unknown
FrameSize x = Video.frameSize;
// but this line compiles fine - Object class is public
Object y = Video.frameSize;
}
}
NetBeans warns you about this, because most likely it is unintentional error - why do you want to make some field value accessible to all without publishing the type of this field, that in effect prevents them from using that field ?
If you want make the variable accessible only to other classes within the same package, declare it as protected, not public.
But if it is an intentional declaration - then ignore the warning and leave it as is.

Categories

Resources