I don't really know exactly how to word this but basically I need to get the child class instance of an Actor without assigning it (if that makes since?). Is this possible?
package org.game.world.entity.actor;
import java.util.HashMap;
import java.util.Map;
import org.game.world.entity.Entity;
import org.game.world.entity.actor.npc.NPC;
import org.game.world.entity.actor.player.Player;
import org.game.world.entity.actor.player.PlayerData;
public abstract class Actor extends Entity {
/**
* The type of Actor this Entity should be
* recognized as.
*/
private final ActorType actorType;
/**
* A map of ActionStates, not necessarily 'Attributes'.
*/
private final Map<ActionState, Boolean> actionState = new HashMap<ActionState, Boolean>();
/**
* Constructs a new Actor {#Entity}.
*/
public Actor(ActorType actorType) {
this.actorType = actorType;
actionState.putAll(ActionState.DEFAULT_ACTION_STATES);
}
/**
* Gets the status of a {#Actor} ActionSate.
* #param state The ActionState.
* #return The ActionState flag.
*/
public boolean getActionState(ActionState state) {
return actionState.get(state);
}
/**
* Sets a {#Actor} ActionState flag.
* #param state The ActionState.
* #param flag The flag true:false.
*/
public void setActionState(ActionState state, boolean flag) {
actionState.put(state, flag);
}
/**
* Resets all ActionState's for this Actor.
*/
public void setDefaultActionStates() {
actionState.putAll(ActionState.DEFAULT_ACTION_STATES);
}
/**
* Checks if this Actor is a specific ActorType (i.e NPC)
* #param actorType The ActorType
* #return
*/
public boolean isActorType(ActorType actorType) {
return this.actorType == actorType;
}
/**
* The type of Actor.
*/
public static enum ActorType {
PLAYER,
NPC
}
}
An Actor type.
package org.game.world.entity.actor.player;
import org.game.world.entity.Location;
import org.game.world.entity.actor.Actor;
import org.game.world.entity.actor.SkillLink;
/**
* This class represents a Player {#Actor} in the world.
*
* #author dillusion
*
*/
public class Player extends Actor {
/**
* This Player objects unique set of stored
* data.
*/
private final PlayerData playerData;
/**
* Creates a new Player object in the world.
* #param playerData The set of data unique to this Player.
*/
public Player(PlayerData playerData) {
super(ActorType.PLAYER);
this.playerData = playerData;
}
/**
* Gets the players name.
* #return The name.
*/
public String getName() {
return playerData.name;
}
/**
* Gets the players password.
* #return The password.
*/
public String getPassword() {
return playerData.password;
}
/**
* Gets the players permission level.
* #return The permission.
*/
public Permission getPermission() {
return playerData.permission;
}
/**
* Gets the players SkillLink instance.
* #return The SkillLink.
*/
public SkillLink getSkillLink() {
return playerData.skillLink;
}
#Override
public Location getLocation() {
return playerData.location;
}
#Override
public Location setLocation(Location location) {
return playerData.location = location;
}
}
But let's say I have multiple 'Actors'. I don't want to have to cast if I don't need to.
Sorry if I didn't explain this very well.
I dont know what are you questioning about here - so what i have figured out that you might want to do is to use Player as Actor right? Well that is possible by Java standard and inheritance
Actor temp=new Actor(){//implementing abstract methods if any}
Actor player=new Player(); //that is still fine as Actor is common superclas for player and actor
Player another=(Player)player; // thats just fine after typecasting
////but
another=player; // compile error, type mismatch
another=(Player)temp; // ClassCastException but no compilation error;
But still you can use different Actors and Players as Actors.
Related
We are trying to run some standard Java code to send a message via Javamail from a 3rd part application, problem we have is there is a bug in the application meaning it isn't able to use inner classes.
Before anyone asks, please don't ask to fix the application, as it's not within our control. The company who owns the application has suggested others resolve the issue by creating a separate class, instead of using the inner class of RecipientType within setRecipients.
We have tried to no avail to get this to work, creating a new class for RecipientType, although we are having trouble referencing it as it's not a method within setRecipients.
Would be grateful if anyone has an idea of how to get round having to use an inner class within MimeMessage? Is there a way we can hard code this?
Additional info:
This is what we are calling in the application
// new MIME message, version 1.0:
javax.mail.Message message = new javax.mail.internet.MimeMessage(session);
message.setHeader("MIME-Version" , "1.0" );
message.setFrom(new javax.mail.internet.InternetAddress(fromEmailAddress, fromEmailPersonal ));
message.setRecipients(javax.mail.Message.RecipientType.TO, javax.mail.internet.InternetAddress.parse( recipientEmailAddress ));
message.setSubject( emailSubject );
message.setText(emailBody);
javax.mail.Transport.send(message);
This is the section of Message.java that is failing
/**
* This inner class defines the types of recipients allowed by
* the Message class. The currently defined types are TO,
* CC and BCC.
*
* Note that this class only has a protected constructor, thereby
* restricting new Recipient types to either this class or subclasses.
* This effectively implements an enumeration of the allowed Recipient
* types.
*
* The following code sample shows how to use this class to obtain
* the "TO" recipients from a message.
* <blockquote><pre>
*
* Message msg = folder.getMessages(1);
* Address[] a = m.getRecipients(Message.RecipientType.TO);
*
* </pre></blockquote>
*
* #see javax.mail.Message#getRecipients
* #see javax.mail.Message#setRecipients
* #see javax.mail.Message#addRecipients
*/
public static class RecipientType implements Serializable {
/**
* The "To" (primary) recipients.
*/
public static final RecipientType TO = new RecipientType("To");
/**
* The "Cc" (carbon copy) recipients.
*/
public static final RecipientType CC = new RecipientType("Cc");
/**
* The "Bcc" (blind carbon copy) recipients.
*/
public static final RecipientType BCC = new RecipientType("Bcc");
/**
* The type of recipient, usually the name of a corresponding
* Internet standard header.
*
* #serial
*/
protected String type;
private static final long serialVersionUID = -7479791750606340008L;
/**
* Constructor for use by subclasses.
*
* #param type the recipient type
*/
protected RecipientType(String type) {
this.type = type;
}
/**
* When deserializing a RecipientType, we need to make sure to
* return only one of the known static final instances defined
* in this class. Subclasses must implement their own
* <code>readResolve</code> method that checks for their known
* instances before calling this super method.
*
* #return the RecipientType object instance
* #exception ObjectStreamException for object stream errors
*/
protected Object readResolve() throws ObjectStreamException {
if (type.equals("To"))
return TO;
else if (type.equals("Cc"))
return CC;
else if (type.equals("Bcc"))
return BCC;
else
throw new InvalidObjectException(
"Attempt to resolve unknown RecipientType: " + type);
}
#Override
public String toString() {
return type;
}
}
This is the custom class we tried to implement in place of the inner class, labelled RecipientType
import javax.mail.*;
import javax.activation.*;
import java.lang.*;
import java.io.*;
import java.util.*;
import java.text.ParseException;
public class RecipientType implements Serializable {
/**
* The "To" (primary) recipients.
*/
public static final RecipientType TO = new RecipientType("To");
/**
* The "Cc" (carbon copy) recipients.
*/
public static final RecipientType CC = new RecipientType("Cc");
/**
* The "Bcc" (blind carbon copy) recipients.
*/
public static final RecipientType BCC = new RecipientType("Bcc");
/**
* The type of recipient, usually the name of a corresponding
* Internet standard header.
*
* #serial
*/
protected String type;
private static final long serialVersionUID = -7479791750606340008L;
/**
* Constructor for use by subclasses.
*
* #param type the recipient type
*/
protected RecipientType(String type) {
this.type = type;
}
/**
* When deserializing a RecipientType, we need to make sure to
* return only one of the known static final instances defined
* in this class. Subclasses must implement their own
* <code>readResolve</code> method that checks for their known
* instances before calling this super method.
*
* #return the RecipientType object instance
* #exception ObjectStreamException for object stream errors
*/
protected Object readResolve() throws ObjectStreamException {
if (type.equals("To"))
return TO;
else if (type.equals("Cc"))
return CC;
else if (type.equals("Bcc"))
return BCC;
else
throw new InvalidObjectException(
"Attempt to resolve unknown RecipientType: " + type);
}
#Override
public String toString() {
return type;
}
}
This is how we tried implementing the custom class
message.setRecipients(RecipientType.TO,
javax.mail.internet.InternetAddress.parse( recipientEmailAddress ));
We get the following error:
Unable to parse expression; undefined method: addRecipient for class: javax.mal.Message (line: 29, col:2)
Forgive me if this is a stupid question, I've been doing iphone and android for a while now and recently I need to develop for the web.
I'm using parse.com to handle my server requests. According to their documentation, I can do a subclass like this.
//A complex subclass of Parse.Object
var Monster = Parse.Object.extend("Monster", {
// Instance methods
hasSuperHumanStrength: function () {
return this.get("strength") > 18;
},
// Instance properties go in an initialize method
initialize: function (attrs, options) {
this.sound = "Rawr"
}
}, {
// Class methods
spawn: function(strength) {
var monster = new Monster();
monster.set("strength", strength);
return monster;
}
});
var monster = Monster.spawn(200);
alert(monster.get('strength')); // Displays 200.
alert(monster.sound); // Displays Rawr.
Ultimately I'm trying to translate the following code from Java to JS.
/**
* #author XujieSong
*
*/
#ParseClassName("_User")
public class SHUser extends ParseUser {
/**
* SHUser is a subclass of ParseUser
* Class name _User
*/
/**
* Default constructor
*/
public SHUser() {
}
/**
* Create a SHUser object with known objectId
* This method only returns a SHUser without data
* #param userID the objectId of the SHUser
* #return user a reference to a SHUser
*/
public SHUser(String userId) {
this.setObjectId(userId);
}
/**
* Create a new SHUser with attributes
* #param userName
* #param password
* #param email
* #param displayName
* #param installation
* #param profileImage
* #return user a new user
*/
public SHUser(String userName, String password, String email, String displayName) {
this.setUsername(userName);
this.setPassword(password);
this.setEmail(email);
this.setDisplayName(displayName);
}
}
And this is what I have got so far,
var SHUser = Parse.Object.extend("_User", {
/**
* Instance properties go in an initialize method
* #param {userId}
* #return {[type]}
*/
SHUser: function () {
},
/**
* Instance properties go in an initialize method
* #param {userId}
* #return {[type]}
*/
SHUser: function (userId) {
this.id = userId;
},
/**
* Instance properties go in an initialize method
* #param {userName}
* #param {password}
* #param {email}
* #param {displayName}
* #return {[type]}
*/
SHUser: function (userName, password, email, displayName) {
this.setUsername(userName);
this.setPassword(password);
this.setEmail(email);
this.setDisplayName(displayName);
}
}, {
// Class methods
});
after
var user = new SHUser(userId);
window.alert(Shelf.seller.id);
I got undefined.
So here's the question. Is it possible to have a default constructor, then a few customized constructors like the way it is in Java? Is it a good practice to do so? Thank you.
After further digging in Backbone.js, I've found the answer.
Turns out there's no need for any additional coding.
var SHUser = Parse.Object.extend("_User", {
/**
* Instance properties go in an initialize method
*/
initialize: function (attr, options) {
},
}, {
// Class methods
});
It's a backbone.js model, so when initializing, just pass the parameters in and it would work.
var seller = new SHUser({"id": sellerId});
And that's it!
For more information please refer to backbonejs.org
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 8 years ago.
Improve this question
Selected lines "<------- These" gives an erroror: This method requires a body instead of a semicolon
Both files must work together.
How to fix it I need quick help. Does anyone have any idea but i dont?
package API.Info;
import Mains.MiniEvents;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import java.util.HashMap;
public class ApiInfo {
public static MiniEvents plugin;
public ApiInfo(MiniEvents plugin) {
ApiInfo.plugin = plugin;
}
/**
* #return number of players in the event.
*/
public int eventSize() {
return plugin.getInfo().eventSize();
}
/**
* #return "code" name of the current event running; else, "none"
* It will return one of the following:
* horse, koth, oitc, paint, tdm, ko, lms, parkour, spleef, tnt
*/
public String getEventName() {
return plugin.getInfo().getEventName();
}
/**
* #return TRUE if an event is starting (counting down).
*/
public boolean eventStarting(){
return plugin.getInfo().eventStarting();
}
/**
* #return TRUE if an event has started.
*/
public boolean eventStarted(); <------- These
/**
* #param player - Player to check.
* #return TRUE if a player is currently playing in an event.
*/
public boolean inEvent(Player player); <------- These
/**
* #return the "formal" name of an event that is running.
* param eventName - the event for which to return the formal name for.
*/
public String eventFormalEventName(String eventName); <------- These
/**
* #return time left until the event starts
*/
public int getTimeLeft(); <------- These
/**
* #param player - Gets that player's file.
* #return the FileConfiguration where individual player data is stored.
*/
public FileConfiguration getPlayerFile(Player player); <------- These
/**
* The is a big "inevent" HashSet<Player> that contains a player no matter what event
* that player is in.
*
* #return the "inevent" HashSet.
*/
public HashMap<String, String> getPlayersInEvent(); <------- These
/**
* #return true if a player is currently in spectate mode.
*/
public boolean inSpectateMode(Player player); <------- These
}
File Info.jar
package Util.Methods;
import API.Info.ApiInfo;
import Mains.MiniEvents;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.Scoreboard;
import java.util.HashMap;
import java.util.HashSet;
public class Info extends ApiInfo{
public MiniEvents plugin;
public Info(MiniEvents plugin) {
super(plugin);
this.plugin = plugin;
}
public boolean eventstarting = false;
public boolean eventstarted = false;
public boolean cancelled = false;
public final HashSet<String> sbefore = new HashSet<>();
public final HashSet<String> sblue = new HashSet<>();
public final HashSet<String> sred = new HashSet<>();
public final HashSet<String> sfire = new HashSet<>();
public final HashMap<String, String> inevent = new HashMap<>();
public final HashMap<String, Scoreboard> scoreboard = new HashMap<>();
public int eventSize(){
return inevent.size();
}
public String getEventName(){
return plugin.getEventName();
}
public boolean eventStarting(){
return eventstarting;
}
public boolean eventStarted(){
return eventstarted;
}
public boolean inEvent(Player player){
return inevent.containsKey(player.getName());
}
public String eventFormalEventName(String s){
return plugin.getFormalName(s);
}
public int getTimeLeft(){
return plugin.getTimerMain().getTimeLeft();
}
public FileConfiguration getPlayerFile(Player player){
return plugin.playerFile(player.getName().toLowerCase());
}
public HashMap<String, String> getPlayersInEvent(){
return inevent;
}
public boolean inSpectateMode(Player player){
return plugin.getSpectateMode().inspec.contains(player.getName());
}
}
You are trying to define a method without defining it. Methods (when not being abstract or declared in interfaces) always need the method head (void method()) and a body ({ ... }). In the lines you have marked, you are only defining the head but not the body.
If you want to have this method declared without instantly defining the body, you need to make them abstract.
I am working on adding support for property observations for my open source library droidQuery, however the propertyChange method is not being called in my tests. What do I need to do to get this to work? Here is my code:
ViewObserver.java
package self.philbrown.droidQuery;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import android.view.View;
/**
* Provides Property Change Listening to simulate bindings
* #author Phil Brown
*
*/
public class ViewObserver implements PropertyChangeListener
{
/** The function to call when the interface's method is invoked. */
private Function function;
/**
* Constructor
* #param droidQuery an instance of droidQuery
* #param function the function to call when the value changes. Will include a {#link Observation}
* Object with information about the KVO operation.
*/
public ViewObserver(Function function)
{
this.function = function;
}
#Override
public void propertyChange(PropertyChangeEvent event) //<-- This is never reached!
{
Observation observation = new Observation(event);
function.invoke($.with((View) event.getSource()), observation);
}
/**
* Represents an observation event that occured.
*/
public static class Observation
{
/** The old value prior the this Observation */
public Object oldValue;
/** The new value */
public Object newValue;
/** The name of the property that has changed from {#code oldValue} to {#code newValue}. */
public String property;
/**
* Constructor. Private since it is only used locally.
* #param event
*/
private Observation(PropertyChangeEvent event)
{
oldValue = event.getOldValue();
newValue = event.getNewValue();
property = event.getPropertyName();
}
}
}
Relevant portions of droidQuery.java (the rest available on github):
/** Used for Property Change Listening to simulate KVO Binding in droidQuery */
private static Map<View, Map<String, WeakReference<Observer>>> observers;
//The constructor has this:
//if (observers == null)
// observers = new HashMap<View, Map<String, WeakReference<Observer>>>();
/**
* Observe changes to the given property and respond to modification events. This requires
* a getter and setter method for the given property on the selected views. Passing "*" will
* add the property observer for all of the fields in each selected view. For example:
* <pre>
* $.with(myButton).observe("selected", new Function() {
* #Override
* public void invoke($ droidQuery, Object... params) {
* Observation ob = (Observation) params[0];
* Log.i("$", ob.property + " changed to " + ob.newValue);
* }
* });
* </pre>
* #param property name of the property to observe. If set to "*", all fields will be observed.
* #param onPropertyChanged the Function to call when the given property has changed. The argument
* passed to {#code onPropertyChanged} will be an instance of {#link ViewObserver.Observation},
* and will contain the old value, new value, and the property name. The given instance of droidQuery
* will have the observing view selected.
*/
public $ observe(String property, Function onPropertyChanged)
{
for (View view : views)
{
Map<String, WeakReference<Observer>> kvo = observers.get(view);
if (kvo == null)
{
kvo = new HashMap<String, WeakReference<Observer>>();
}
WeakReference<Observer> ref = kvo.get(property);
if (ref != null && ref.get() != null)
{
if (property.equals("*"))
ref.get().support.removePropertyChangeListener(ref.get().kvo);
else
ref.get().support.removePropertyChangeListener(property, ref.get().kvo);
}
Observer observer = new Observer();
observer.support = new PropertyChangeSupport(view);
observer.kvo = new ViewObserver(onPropertyChanged);
ref = new WeakReference<Observer>(observer);
if (property.equals("*"))
observer.support.addPropertyChangeListener(observer.kvo);
else
observer.support.addPropertyChangeListener(property, observer.kvo);
kvo.put(property, ref);
observers.put(view, kvo);
}
return this;
}
/**
* Contains Objects pertaining to the property change listener for a view in droidQuery.
*/
public static class Observer
{
/** Manages property observers registered to receive events */
public PropertyChangeSupport support;
/** The property observer */
public ViewObserver kvo;
}
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);
}