This is my first Java project.
So I'm working on my own simulation project, and some of my core stuff has gone awry. I have two classes I'm focusing on right now - settlement and townRey, which extends settlement.
The error is thrown when I try
System.out.println(townRey.returnStrength());
Here are my two relevant classes:
settlement:
public class settlement
{
//
//
// VARIABLES
//
//
/**
* The town's unique name.
*/
public String name;
/**
* The settlement's location in latitude (N-S)
*/
public int latitude;
/**
* The settlement's location in longitude (E-W)
*/
public int longitude;
/**
* What faction a town or village is aligned to. This determines production and consumption, mostly.
*/
public String faction;
/**
* What a specific village or town produces.
*/
public String[] production;
/**
* What a specific town consumes (villages don't consume)
*/
public String[] consumption;
/**
* How dangerous a specific town is with bandits
* A 1-10 scale, with 10 being the most dangerous.
* Any town with a danger over 8 can be raided and destroyed temporarily by bandits.
* Being raided successfully depends on the Strength of a town.
*/
public int danger;
/**
* How much a town takes in taxes.
*/
public float tax;
/**
* How easily a town is raided by bandits.
* If a bandit raid has a lower strength than the town, then the town wins.
*/
public int strength;
//
//
// METHODS
//
//
public int returnLatitude()
{
return latitude;
}
public int returnLongitude()
{
return longitude;
}
public String returnFaction()
{
return faction;
}
public String[] returnProduction()
{
return production;
}
public String[] returnConsumption()
{
return consumption;
}
public int returnDanger()
{
return danger;
}
public float returnTax()
{
return tax;
}
public int returnStrength()
{
return strength;
}
}
and townRey:
public class townRey extends settlement
{{
name = "Rey";
latitude = 5;
longitude = 5;
String faction = "Nord";
String[] production;
String[] consumption;
danger = 1;
tax = 0.05F;
strength = 6;
}}
EDIT:: Thanks for all the help! I fixed all issues now. Below is 'Settlement' and 'Start'.
public class Settlement
{
//
//
// VARIABLES
//
//
/**
* The town's unique name.
*/
public String name;
/**
* The settlement's location in latitude (N-S)
*/
public int latitude;
/**
* The settlement's location in longitude (E-W)
*/
public int longitude;
/**
* What faction a town or village is aligned to. This determines production and consumption, mostly.
*/
public String faction;
/**
* What a specific village or town produces.
*/
public String[] production;
/**
* What a specific town consumes (villages don't consume)
*/
public String[] consumption;
/**
* How dangerous a specific town is with bandits
* A 1-10 scale, with 10 being the most dangerous.
* Any town with a danger over 8 can be raided and destroyed temporarily by bandits.
* Being raided successfully depends on the Strength of a town.
*/
public int danger;
/**
* How much a town takes in taxes.
*/
public float tax;
/**
* How easily a town is raided by bandits.
* If a bandit raid has a lower strength than the town, then the town wins.
*/
public int strength;
//
//
// METHODS
//
//
public int returnLatitude()
{
return latitude;
}
public int returnLongitude()
{
return longitude;
}
public String returnFaction()
{
return faction;
}
public String[] returnProduction()
{
return production;
}
public String[] returnConsumption()
{
return consumption;
}
public int returnDanger()
{
return danger;
}
public float returnTax()
{
return tax;
}
public int returnStrength()
{
return strength;
}
}
and Start, where I create 'townRey' then access a bit of data in two different ways.
public class Start
{
public static void main(String[] args)
{
//Creates 'Rey'
Settlement townRey = new Settlement();
townRey.name = "Rey";
townRey.latitude = 5;
townRey.longitude = 5;
townRey.faction = "Nord";
townRey.danger = 1;
townRey.tax = 0.05F;
townRey.strength = 6;
//This calls the returnLongitude method from Settlement, and is the 'proper' way to do it.
System.out.println(townRey.returnLongitude());
//This also works.
System.out.println(townRey.longitude);
//Thanks for the help!
}
}
townRey shouldn't be extending settlement. You should be declaring it as an instance of settlement in some method, as follows:
townRey = new settlement();
townRey.name = "Rey";
...
townRey.strength = 6;
Or, better still, making a new constructor for settlement that takes the different fields as inputs.
Also, a style note: Generally, in Java, classes should begin with a capital letter, so Settlement rather than settlement might make a better name.
You should define a townRey object then use this object to call returnStrength
townRey mytownRey = new townRey();
System.out.println(townRey.returnStrength());
I expect you want townRey to be an instance of settlement, not a subclass. Unless you want to have multiple copies of townRey. Replace the line public class townRey extends settlement with settlement townRey = new settlement(), and add a semicolon after }}. Leave everything else the same.
public class mainclss()
{
public static void main(String arg[])
{
townRey= new settlement();
//you can do sth you like
}
}
create a new class to check.DO NOT start Java with Class!It is a little difficult.
Create a separate class with main() method. Inside this method, you should create an object of townRey, in order to access the method returnStrength(). You can't access it using the class name 'townRay' if you are doing so. So Add this class with the code below:
public class MainClass {
public static void main(String[] args) {
townRey tr = new townRey();
System.out.println( tr.returnStrength () );
}
}
This worked fine with me. So you can safely use it.
NOTE: You should learn by practice to start each word in your class name with a capital letter such as Settlement and TownRey. Good Luck!
Related
I was trying to construct an object of the MTree class (https://github.com/Waikato/moa/blob/master/moa/src/main/java/moa/clusterers/outliers/utils/mtree/MTree.java)
The constructor of MTree looks like this:
public MTree(DistanceFunction<? super DATA> distanceFunction,
SplitFunction<DATA> splitFunction) {
this(DEFAULT_MIN_NODE_CAPACITY, distanceFunction, splitFunction);
}
The DistanceFunction here is an interface, the code of it is:
/**
* An object that can calculate the distance between two data objects.
*
* #param <DATA> The type of the data objects.
*/
public interface DistanceFunction<DATA> {
double calculate(DATA data1, DATA data2);
}
And it's implementation is:
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Some pre-defined implementations of {#linkplain DistanceFunction distance
* functions}.
*/
public final class DistanceFunctions {
/**
* Don't let anyone instantiate this class.
*/
private DistanceFunctions() {}
/**
* Creates a cached version of a {#linkplain DistanceFunction distance
* function}. This method is used internally by {#link MTree} to create
* a cached distance function to pass to the {#linkplain SplitFunction split
* function}.
* #param distanceFunction The distance function to create a cached version
* of.
* #return The cached distance function.
*/
public static <Data> DistanceFunction<Data> cached(final DistanceFunction<Data> distanceFunction) {
return new DistanceFunction<Data>() {
class Pair {
Data data1;
Data data2;
public Pair(Data data1, Data data2) {
this.data1 = data1;
this.data2 = data2;
}
#Override
public int hashCode() {
return data1.hashCode() ^ data2.hashCode();
}
#Override
public boolean equals(Object arg0) {
if(arg0 instanceof Pair) {
Pair that = (Pair) arg0;
return this.data1.equals(that.data1)
&& this.data2.equals(that.data2);
} else {
return false;
}
}
}
private final Map<Pair, Double> cache = new HashMap<Pair, Double>();
#Override
public double calculate(Data data1, Data data2) {
Pair pair1 = new Pair(data1, data2);
Double distance = cache.get(pair1);
if(distance != null) {
return distance;
}
Pair pair2 = new Pair(data2, data1);
distance = cache.get(pair2);
if(distance != null) {
return distance;
}
distance = distanceFunction.calculate(data1, data2);
cache.put(pair1, distance);
cache.put(pair2, distance);
return distance;
}
};
}
/**
* An interface to represent coordinates in Euclidean spaces.
* #see <a href="http://en.wikipedia.org/wiki/Euclidean_space">"Euclidean
* Space" article at Wikipedia</a>
*/
public interface EuclideanCoordinate {
/**
* The number of dimensions.
*/
int dimensions();
/**
* A method to access the {#code index}-th component of the coordinate.
*
* #param index The index of the component. Must be less than {#link
* #dimensions()}.
*/
double get(int index);
}
/**
* Calculates the distance between two {#linkplain EuclideanCoordinate
* euclidean coordinates}.
*/
public static double euclidean(EuclideanCoordinate coord1, EuclideanCoordinate coord2) {
int size = Math.min(coord1.dimensions(), coord2.dimensions());
double distance = 0;
for(int i = 0; i < size; i++) {
double diff = coord1.get(i) - coord2.get(i);
distance += diff * diff;
}
distance = Math.sqrt(distance);
return distance;
}
/**
* A {#linkplain DistanceFunction distance function} object that calculates
* the distance between two {#linkplain EuclideanCoordinate euclidean
* coordinates}.
*/
public static final DistanceFunction<EuclideanCoordinate> EUCLIDEAN = new DistanceFunction<DistanceFunctions.EuclideanCoordinate>() {
#Override
public double calculate(EuclideanCoordinate coord1, EuclideanCoordinate coord2) {
return DistanceFunctions.euclidean(coord1, coord2);
}
};
/**
* A {#linkplain DistanceFunction distance function} object that calculates
* the distance between two coordinates represented by {#linkplain
* java.util.List lists} of {#link java.lang.Integer}s.
*/
public static final DistanceFunction<List<Integer>> EUCLIDEAN_INTEGER_LIST = new DistanceFunction<List<Integer>>() {
#Override
public double calculate(List<Integer> data1, List<Integer> data2) {
class IntegerListEuclideanCoordinate implements EuclideanCoordinate {
List<Integer> list;
public IntegerListEuclideanCoordinate(List<Integer> list) { this.list = list; }
#Override public int dimensions() { return list.size(); }
#Override public double get(int index) { return list.get(index); }
};
IntegerListEuclideanCoordinate coord1 = new IntegerListEuclideanCoordinate(data1);
IntegerListEuclideanCoordinate coord2 = new IntegerListEuclideanCoordinate(data2);
return DistanceFunctions.euclidean(coord1, coord2);
}
};
/**
* A {#linkplain DistanceFunction distance function} object that calculates
* the distance between two coordinates represented by {#linkplain
* java.util.List lists} of {#link java.lang.Double}s.
*/
public static final DistanceFunction<List<Double>> EUCLIDEAN_DOUBLE_LIST = new DistanceFunction<List<Double>>() {
#Override
public double calculate(List<Double> data1, List<Double> data2) {
class DoubleListEuclideanCoordinate implements EuclideanCoordinate {
List<Double> list;
public DoubleListEuclideanCoordinate(List<Double> list) { this.list = list; }
#Override public int dimensions() { return list.size(); }
#Override public double get(int index) { return list.get(index); }
};
DoubleListEuclideanCoordinate coord1 = new DoubleListEuclideanCoordinate(data1);
DoubleListEuclideanCoordinate coord2 = new DoubleListEuclideanCoordinate(data2);
return DistanceFunctions.euclidean(coord1, coord2);
}
};
}
And my first question is what's the meaning of return new DistanceFunction<Data>() in the method public static <Data> DistanceFunction<Data> cached(final DistanceFunction<Data> distanceFunction) [the method is in the class DistanceFunctions] I am just a beginner of Java and this one is a little bit hard for me to understand.
Also, to create an object of MTree, I should create an object of DistanceFunctions and an object of ComposedSplitFunction(Which is the implementation of SplitFunction interface) and input them as parameter for MTree constructor. But I really don't know how to do that because in DistanceFunctions class, the constructor is private. So I cannot generate a parameter for the constructor of MTree.
What should I do?
New Update: What I want to do is create a Junit Test for MTree, and I believe the first thing I need to do is create an object of MTree.
Interfaces can have multiple implementations. They just form the general contract implementations need to follow.
The cache implementation here i.e. takes a DistanceFunction as input and guarantees that distance values between A and B (or B and A) are only calculated once and thereafter served from the internal cache map. The generic type of that cache function just guarantees that you can literally pass any type to it. I.e. you could have an implementation that takes in its simplest form just two integers and calculates the difference of these like this:
DistanceFunction<Integer> func = (Integer a, Integer b) -> Math.abs(a - b);
which is a labmda expression which could be also written a bit more verbose like this
DistanceFunction<Integer> func = new DistanceFunction<Integer>() {
#Override
public double calculate(Integer data1, Integer data2) {
return Math.abs(data1 - data2);
}
};
and then use it like that to cache the return value for the provided input parameters:
DistanceFunction<Integer> cache = DistanceFunctions.cached(func);
double distance = cache.calculate(10, 5);
If you later on have a call like
distance = cache.calculate(10, 5);
again or even
distance = cache.calculate(5, 10);
The distance value in the above case is not recalculated but its value is returned from the internal cache map as the distance for these parameters was already calculated before. This is especially benefitial if you have plenty of data points but only a limited number of combination of these and calculation is rather expensive.
If you further look into the DistanceFunctions class you've provided you will see that it already provides some implementations for i.e. EUCLIDEAN, EUCLIDEAN_INTEGER_LIST and EUCLIDEAN_DOUBLE_LIST implementations which due to their static final nature can be used as constant in your code directly. Here you just need to provide matching input arguments to the calculate(...) method based on the implementation you've chosen.
In regards to Waikato's MTree` initialization, a rough template may look like this:
MTree mTree = new MTree(EUCLIDEAN_INTEGER_LIST, new SplitFunction<List<Integer>>(...) {
...
#Override
public SplitResult<List<Integer>> process(Set<List<Integer>> dataSet, DistanceFunction<? super List<Integer>> distanceFunction) {
Pair<List<Integer>> promoted = ...
Pair<Set<List<Integer>>> partitions = ...
return new SplitResult<List<Integer>>(promoted, partitions);
}
});
where the parts outlined by ... need to be defined and implemented by you. The code in that package though provides i.e. a ComposedSplitFunction implementation already that requires PartitionFunction and PromotionFunction as inputs where implementations of these are already available in the PartitionFunctions and PromotionFunctions classes that just work the same way as the DistanceFunction and DistanceFunctions discussed here.
I am starting to develop my skills in JAVA, however I have a doubt.
I'm creating an object in JAVA, created the constructor and so on, then, it asks "Change the AGE_RECENT value from 1 to 3", I initially declared this as final because I never thought it would change, so no SET or GET were created. I am wondering how can I change the value from 1 to 3 in the SET Method.
I have this variable
private static int AGE_RECENT=1;
I did this.
public void setAgeRecent() {
Vehicle.AGE_RECENT = 3;
}
It works if you run the program, it changes the variable's value, however nothing was declared in that method as every SET method.
Just wondering how can I do this. If this is correct, good, if not, thanks for helping!
As someone asked, the code.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package tp1;
/**
*
* #author Nelson
*/
public class Vehicle {
/** Variáveis da classe, têm como função **/
private String registration;
private int registrationYear;
private double consumption;
private double autonomy;
private int cilinderCapacity;
/**
* Final variables. They are final because they do not suffer any kind of modification during the project.
* YEAR_OMISSION is 2016 because the currect year is 2016.
* ENVIRONMENTAL_CHARGE_OMISSION is 0.10(10 cents), gave this value because there is nothing to mention the
especific value, hence why I gave 0.10.
* RATING_RECENT = Is a string, just has the text "RECENT" inside.
* RATING_COMTEMPORY - Another string, just with the "Comtempory" text inside.
* RATING_CLASSIC - Yet again another string, with the "Classic" text.
* AGE_RECENT - It is to help to compare if a vehicle is recent or not, it has the value 3.
* AGE_CLASSIC - It is to again help to compare, value is 20.
*/
private static final int YEAR_OMISSION = 2016;
private static final double ENVIRONMENTAL_CHARGE_OMISSION=0.10;
private static final String RATING_RECENT="Recent";
private static final String RATING_CONTEMPORY="Contempory";
private static final String RATING_CLASSIC="Classic";
private static int AGE_RECENT=1;
private static final int AGE_CLASSIC=20;
/**
* Constructor of the object, it has the Registration
* #param registration
* #param registrationYear - The year the vehicle was first registered.
* #param consumption - How many liters the vehicle consumes.
* #param autonomy - How many KMs a vehicle can go without refuelling.
* #param cilinderCapacity - How many Cubic Inches the engine has.
*/
public Vehicle(String registration,int registrationYear, double consumption, double autonomy, int cilinderCapacity) {
this.registration = registration;
this.registrationYear = registrationYear;
this.consumption = consumption;
this.autonomy = autonomy;
this.cilinderCapacity = cilinderCapacity;
}
/**
* Null Constructor, it has no values, they will be attributed in the MAIN Class.
*/
public Vehicle() {
this.registration = "";
this.registrationYear = 0;
this.consumption = 0;
this.autonomy = 0;
this.cilinderCapacity =0;
this.registrationYear = YEAR_OMISSION;
}
/**
* Copy Constructor.
*/
public Vehicle(Vehicle vehicle) {
this.registration = vehicle.getRegistration();
this.registrationYear = vehicle.getRegistrationYear();
this.consumption = vehicle.getConsumption();
this.autonomy = vehicle.getAutonomy();
this.cilinderCapacity = vehicle.getCilinderCapacity();
}
public String getRegistration() {
return registration;
}
public int getRegistrationYear() {
return registrationYear;
}
public double getConsumption() {
return consumption;
}
public double getAutonomy() {
return autonomy;
}
public int getCilinderCapacity() {
return cilinderCapacity;
}
public double getYearRecent() {
return AGE_RECENT;
}
public double getAgeRecent(){
return AGE_RECENT;
}
public void setRegistration(String registration) {
this.registration = registration;
}
public void setRegistrationYear(int registrationYear) {
this.registrationYear = registrationYear;
}
public void setConsumption(double consumption) {
this.consumption = consumption;
}
public void setAutonomy(double autonomy) {
this.autonomy = autonomy;
}
public void setCilinderCapacity(int cilinderCapacity) {
this.cilinderCapacity = cilinderCapacity;
}
public void setAgeRecent() {
Vehicle.AGE_RECENT = 3;
}
/**
* Calculate the age of the vehicle to compare in the vehicleRating method
* #return The year, which is 2016 minus the year the vehicle was first registered.
*/
private int calculateAge(){
return YEAR_OMISSION-this.registrationYear;
}
/**
* Calculate the Circulation Tax.
* #return Returns the value of the Environmental Charge multiplied by the Cilinder Capacity of the vehicle.
*/
public double calculateCirculationTax(){
return ENVIRONMENTAL_CHARGE_OMISSION*cilinderCapacity;
}
/**
* Classify the vehicle based on the age.
* If the result given by the calculateAge method is minor than the AGE_RECENT variable(3), then it will
return "Recent"
* If the result is between Age_RECENT and AGE_CLASSIC(20), then it will say "Contemporary"
* If none of the IFs apply, it will return "Classic".
**/
public static String vehicleRating(Vehicle vehicle) {
if(vehicle.calculateAge() < Vehicle.AGE_RECENT) {
return Vehicle.RATING_RECENT; }
else if ((vehicle.calculateAge()>=Vehicle.AGE_RECENT)&&(vehicle.calculateAge()<=Vehicle.AGE_CLASSIC)){
return Vehicle.RATING_CONTEMPORY;}
else
return Vehicle.RATING_CLASSIC;
}
#Override
public String toString() {
return "Vehicle{" + "registration=" + registration + ", registrationYear=" + registrationYear + ", consumption=" + consumption + ", autonomy=" + autonomy + ", cilinderCapacity=" + cilinderCapacity + '}';
}
}
A setter that takes no arguments is simply a method, not a setter. In order to work as a setter a method must take a parameter that matches the type of the value being set - in your case, that would be int:
public static void setAgeRecent(int age) {
AGE_RECENT = age;
}
Note a few things here:
Since AGE_RECENT is static, setAgeRecent should be static
Since AGE_RECENT and setAgeRecent are static members of the same class Vehicle, you do not need to qualify AGE_RECENT with Vehicle
Now users of your class would be able to call your static setter as follows:
Vehicle.setAgeRecent(3);
A static varible, or class variable, may be used without the need to create an instance of that class. But its value may be changed freely at runtime.
A final variable is not a variable in a true sense, because it's value can't be changed at runtime.
Thus, you may have a set method for a static variable, but never to a final variable.
My question is: How do I access values from another thread?
I have two .java files, Main.java and TrackHands.java
Main.java
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
Thread trackHands = new Thread(new TrackHands());
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
* #version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
/**
* run This will be executed when the thread starts
*/
#Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector convertedLeftHand = new PVector();
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
I have tried to use a getter and a setter to get the values from TrackHands.java into another thread.
Tried creating objects and passing the values as parameters, but then my program will not use these new values in the run() method.
To get values from TrackHands, use a get method that accesses an instance variable that is set in run()
class TrackHands {
Object output;
public void run() {
while(true) {
output = new Object();
}
}
public Object getOutput() {
return output;
}
}
Pass TrackHands into your consumer object and use it to call get getOutput() method.
Passing values in is a bit trickier, because you might cause race condition. Try something like this
class TrackHands {
Object input = null;
public boolean setInput(Object input) {
if(this.input == null) {
this.input = input;
return true;
} else {
return false;
}
}
}
When your run() method uses input, set it to null so that another thread can pass in another input. Your producer thread will use this loop to pass in input:
public void sendInput(TrackHands th, Object input) {
boolean done = false;
while(!done) {
done = th.setInput(input);
}
}
This will keep trying to pass in input until it succeeds.
setInput uses the synchronized keyword so that only one thread can call this method at once, otherwise you'll get a race condition.
A friend of mine solved my problem.
I want to thank everyone for helping me!
Main.java
/**
* This is the main class, it is used to start the program. The only use of this
* is to make everything more organized.
*/
package Kinect;
//import processing.core.PApplet;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*
*/
public class Main
{
public static void main(String _args[])
{
// PApplet.main(new String[]
// {
// Sensor.class.getName()
// });
ValueStore valueStore = new ValueStore(); // ADDED THIS LINE
Thread trackHands = new Thread(new TrackHands(valueStore)); // ADDED THIS LINE
trackHands.start();
}
}
TrackHands.java
/*
* This uses the normal Java layout to track the user and prints out the coordinates of the left and right hand
*/
package Kinect;
import SimpleOpenNI.*;
import processing.core.PApplet;
import processing.core.PVector;
/**
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
* #version 1.0
*/
public class TrackHands extends PApplet implements Runnable
{
private int handLeftX, handLeftY, handRightX, handRightY = 0; // Holds the coordinates of the left hand
SimpleOpenNI kinect = new SimpleOpenNI(this); // kinect object
private ValueStore valuesStore; // ADDED THIS LINE
/**
* Constructor Takes no parameters
*/
public TrackHands()
{
}
public TrackHands(ValueStore valuesStore)
{
this.valuesStore = valuesStore;
}
/**
* run This will be executed when the thread starts
*/
#Override
public void run()
{
IntVector userList = new IntVector(); // Make a vector of ints to store the list of users
PVector leftHand = new PVector(); // Make a vector to store the left hand
PVector rightHand = new PVector(); // Make a vector to store the right hand
PVector convertedLeftHand = new PVector(); // Make a vector to store the actual left hand
PVector convertedRightHand = new PVector(); // Make a vector to store the actual right hand
kinect.enableDepth();
kinect.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
kinect.setMirror(true);
while (true)
{
kinect.update();
kinect.getUsers(userList); // Write the list of detected users into the vector
if (userList.size() > 0) // Checks if a user is found
{
int userId = userList.get(0); // Get first user
if (kinect.isTrackingSkeleton(userId)) // If successfully calibrated
{
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_LEFT_HAND, leftHand); // Put the position of the left hand into that vector
kinect.getJointPositionSkeleton(userId,
SimpleOpenNI.SKEL_RIGHT_HAND, rightHand); // Put the position of the left hand into that vector
kinect.convertRealWorldToProjective(leftHand,
convertedLeftHand);
kinect.convertRealWorldToProjective(rightHand,
convertedRightHand);
this.handLeftX = round(convertedLeftHand.x);
this.handLeftY = round(convertedLeftHand.y);
this.handRightX = round(convertedRightHand.x);
this.handRightY = round(convertedRightHand.y);
valuesStore.setHandValues(handLeftX, handLeftY, handRightX, handRightY); // ADDED THIS LINE
}
}
}
}
// User-tracking callbacks!
public void onNewUser(int userId)
{
System.out.println("Start pose detection");
kinect.startPoseDetection("Psi", userId);
}
public void onEndCalibration(int userId, boolean successful)
{
if (successful)
{
System.out.println(" User calibrated !!!");
kinect.startTrackingSkeleton(userId);
} else
{
System.out.println(" Failed to calibrate user !!!");
kinect.startPoseDetection("Psi", userId);
}
}
public void onStartPose(String pose, int userId)
{
System.out.println("Started pose for user");
kinect.stopPoseDetection(userId);
kinect.requestCalibrationSkeleton(userId, true);
}
}
Then added a class to store the values so another class can access it.
ValueStore.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Kinect;
/**
*
* #author Tony Nguyen <Tony.Nguyen#HvA.nl>
*/
public class ValueStore
{
private int leftX, leftY, rightX, rightY = 0;
public void setHandValues(int leftX, int leftY, int rightX, int rightY)
{
this.leftX = leftX;
this.leftY = leftY;
this.rightX = rightX;
this.rightY = rightY;
}
public int getLeftX()
{
return this.leftX;
}
}
Problem: When a skeleton enters a place, I want all the Players screens updated using this method in my World object:
/**
* Say `text' in the Place `place'. The text will become visible at the
* bottom of the text window of any Players currently watching `place'.
*
* #param place
* The place where the string will be displayed.
* #param text
* The string to be diplayed.
*/
public void sayAtPlace(Place place, String text) {
synchronized (players) {
Iterator<Player> ls = players.iterator();
while (ls.hasNext()) {
Player p = ls.next();
if (p.currentPlace() == place) {
p.say(text);
}
}
}
}
I've got two classes, Person and Player and I want a Person to write to the textarea when the method goTo is called but I can't make the Person object have a proper reference to a Player that has the textarea:
package adventure;
import java.awt.*;
import java.util.*;
/**
* ADT for persons which is completed which subclasses to creating actors with
* specific properties
*/
public class Person {
public Player player = null;
/**
* Name of the Person.
*/
public String name;
/**
* The World which this Person is associated with.
*/
public World world;
/**
* Tells where this Person is at the moment.
*/
public Place where;
/**
* Create Person named `name' in world `world'.
*
* #param world
* The world where the Person is created.
* #param name
* Name of the Person.
* #param app
* An image used to display the Person.
*/
public Person(World world, String name, Image app) {
this.world = world;
this.name = name;
this.appearance = app;
// this.player = player;
where = world.defaultPlace();
where.enter(this);
inventory = Collections.synchronizedCollection(new LinkedList<Thing>());
}
/**
* Go directly, and quietly, to 'place'. That is to say, without posting a
* message that you're doing so.
*
* #param place
* A string referring to the Place to go to.
* #see #goTo(Place)
* #see #go
*/
public void goTo(String place) {
goTo(world.getPlace(place), null);
}
/**
* Go directly, and quietly, to `whereTo'. That is to say, without posting a
* message that you're doing so.
*
* #param whereTo
* The Place to go to. Can be null in which case nothing happens.
* #see #goTo(String)
* #see #go
*/
public void goTo(Place whereTo, Player player) {
if (whereTo != null) {
where.exit(this);
whereTo.enter(this);
// Update any Player's which are viewing place `where'.
world.update(where);
// Record our new position.
where = whereTo;
// Also update Player's here.
world.update(where);
}
System.out.println("player:"+player);
if(player != null){
player.say("A terrifying skeleton warrior appears!");
}
// send a msg which doors are available
Object[] doorNames = whereTo.exits.keySet().toArray();
String s = "";
int i = 1;
for (Object obj : doorNames) {
if (i < doorNames.length) {
s = s + obj.toString().toLowerCase();
if(i<doorNames.length){
s = s+ ",";
}
} if (i == doorNames.length && i > 1) {
s = s + " and " + obj.toString().toLowerCase();
}
if (i == doorNames.length && i == 1) {
s = obj.toString().toLowerCase();
}
++i;
}
if (player != null) {
player.say("There are doors " + s);
}
}
package adventure;
import java.awt.*;
/**
* A Player object enables commands to control a certain person: »you». This
* object is displayed graphically as a control panel where the user both can
* control and follow the course of events
*/
public class Player extends Panel {
private Person me;
private PlaceView placeview;
private Commands commands;
private TextArea textarea;
private static final long serialVersionUID = 100L;
/**
* Creates a new instance of Player, in World w, reflecting Person p.
*
* #param w
* The world in which the Player will play in.
* #param p
* The Person associated by Player.
*/
Player(World w, Person p) {
setLayout(new BorderLayout());
setSize(650, 540);
me = p;
p.player = this;
placeview = new PlaceView(me);
commands = new Commands(me);
textarea = new TextArea("", 10, 60, TextArea.SCROLLBARS_VERTICAL_ONLY);
textarea.append("You are in a dungeon. The horrible shrieks of the undead chill your bones.\n");
textarea.setEditable(false);
add("West", placeview);
add("East", commands);
add("South", textarea);
w.addPlayer(this);
}
/**
* Display a string in the players graphical interface.
*
* #param text
* A string to display.
*/
void say(String text) {
textarea.append(text + '\n');
textarea.repaint();
}
/**
* Returns the Place of the Person associated with the Player.
*
* #return The Place of the Person associated with the Player.
*/
public Place currentPlace() {
return me.where;
}
}
Do you understand what I'm trying to do? The code I want to work is
System.out.println("player:"+player);
if(player != null && this.name.equals("Skeleton")){
player.say("A terrifying skeleton warrior appears!");
}
But the player reference of the Person that is a zombie is not instanciated. The only Person who has a Player object instanciated is the Player that is also a Person.
Can you help me? I also posted the full versions of the Person, Player and World classes here
http://pastebin.com/RJCcr2ph (Person)
http://pastebin.com/eYSh8L9Q (Player)
http://pastebin.com/DKvRvEY8 (World)
If I understand your question well, you want to have 2 classes in which each class has a reference to the other. What you need is to create one of them (let it be Foo), create the other class (let it be Boo) and pass a reference of Foo to it via the constructor, and then set a reference of Boo inside Foo class via setter method.
For example:
public static void main(String[] args)
{
Foo f = new Foo();
Boo b = new Boo(f);
f.setBoo(b);
}
class Foo
{
private Boo b;
public Foo()
{
// ...
}
public void setBoo(Boo b)
{
this.b = b;
}
}
class Boo
{
private Foo f;
public Boo(Foo f)
{
this.f = f;
}
}
Now, Foo has a reference of Boo, and Boo has a reference of Foo :)
First , you should instantiate the Person's member 'player' in the constructor .
this.player = new Player(world, this);
Then , change the code from
public void goTo(String place) {
goTo(world.getPlace(place), null);
}
to
public void goTo(String place) {
goTo(world.getPlace(place), this.player);
}
I need to have the teams sortable by order of points, from most to least, i have that i have to write a new method and can make changes to the class header.
I was thinking of using this as my method, but it would put the teams in order of least to most :S so i dont know what way to fix it, also i dont know what changes i would need to make to the class header if any!
public void orderPoints()
{
List<String> points = new ArrayList<String>();
Collections.sort(points);
}
I know i can use Collections.max and min but unsure how i would filter the rest of the points in
Code for rest of the class
public class League
{ /* instance
variables */
private Team name;
private int points;
/**
* Constructor for objects of class League.
*/ public League(Team aname)
{
super();
name = aName;
points = 0; }
/**
* Returns the receiver's name Team
*/ public Team getName() {
return this.name; }
/**
* Returns the receiver's points
*/ public int getPoints() {
return points; }
/**
* Sets the receiver's points
*/ public void setPoints(int aPoints) {
this.points = aPoints; }
I'm not sure I understand what you're asking, but if you want to reverse the sorting of your List you can use Collections.sort(points, Collections.reverseOrder());