How to reference adding objects to ArrayLists inside of objects - java

In JavaFX I am creating a sports tracking system.
My Object User has many Foods and many Exercises, these are stored as ArrayLists.
public class User {
private ArrayList<Food> listofFood = new ArrayList<Food>();
private ArrayList<Exercise> listofExercise = new ArrayList<Exercise>();
private String um;
public User(String u) {
this.um = u;
}
public void addNewFood(Food f) {
listofFood.add(f);
}
public void addNewExercise(Exercise ex) {
listofExercise.add(ex);
}
}
Food and exercise are similar in structure.
public class Food {
private String name;
public Food(String n) {
this.name = n;
}
public void setNameFood(String n) {
this.name = n;
}
}
In my MainApp class I create a user.
public class MainApp {
public User UserLoggedIn;
}
and I pass in an instance of this class using the controller.
public class MainApp {
MyController c = loader.getController();
c.setDialogStage(dialogStage);
c.setApp(this);
}
And in MyController class I set the application ...
public class MyController {
public void setApp(MainApp app) {
this.mainApp = app;
}
}
... which I then reference in MyController.
public class MyController {
mainApp.UserLoggedIn.addNewFood((new Food(nameField.getText())));
}
This gives a Null Pointer exception

UserLoggedIn is never instantiated and it will therefore always be null. Make a default constructor for MainApp() that just creates the User object. Then create a getter method called getUser() that returns the user object. Also, it is Java convention to use camel case instead. So, UserLoggedIn should be userLoggedIn.
public class MainApp
{
private User userLoggedIn;
public MainApp()
{
userLoggedIn = new User("john doe");
}
public User getUserLoggedIn()
{
return userLoggedIn;
}
}
public class MyController
{
MainApp mainApp = new MainApp();
mainApp.getUserLoggedIn().addNewFood(new Food(//enter datum here));
}

Related

Is it possible to make a specific method working only with a specific constructor?

I have a class called User.java
public class User {
public User(Context context) {
}
public User() {
}
public void getUserId(){
}
public void getUserName(){
}
}
If I create an object of user class then I can reach to all methods such as getUserId and getUserName
User user_1 = new User(this);
user_1.getUserId();
user_1.getUserName();
User user_2 = new User();
user_2.getUserId();
user_2.getUserName();
The main question is can I get getUserName only if I called a constructor that has one parameter? But if I call a constructor that does not have a parameter then I can't get getUserName. Is it possible in Java?
There are multiple ways to achieve (roughly) what you want.
The easy, but possibly annoying way is to throw an Exception whenever a "forbidden" method is called:
public String getUserName(){
if (someRequiredContext == null) {
throw new IllegalStateException("method not allowed!");
}
// do stuff
}
This "works", but doesn't help the user avoid calling those methods, since there's no easy way for them to know if they can call getuserName on a given User object.
The more involved version would be to have two classes (for example User and UserWithContext), but then you can't instantiate them the right way. But you could use factory methods instead of constructors:
public abstract class User {
User() { ... };
public static User createUser() {
return new BasicUser();
};
public static UserWithContext createUser(Context context) {
return new UserWithContext(context);
}
public String getId() { ... }
}
class BasicUser extends User { // this class need not be public!
}
public class UserWithContext extends User {
UserWithContext(Context context) { ... }
public String getuserName() { ... };
}
This way the type will inform the users of your API which methods are allowed with a given User object.
No, it is not possible. But you could use interfaces to say for instance LimitedUser and FullUser
public interface LimitedUser {
int userId();
}
public interface FullUser extends LimitedUser {
String getUsername();
}
Then use factory methods on for instance the User implementation
public class User implements FullUser {
private final int id;
private final String username;
private User(int id, String username) {
this.id = id;
this.username = username;
}
public static LimitedUser createLimitedUser(int id) {
return new User(id, null);
}
public static FullUser createFullUser(int id, String username) {
return new User(id, username);
}
public int getId() {
return id;
}
public String getUsername() {
return username;
}
}

Java: Calling a parent's method with child's member variable

Let's say I have an abstract parent class that has member variables which are used in a method.
public abstract class Person{
public String jobTitle;
public void printJob(){
System.out.println(jobTitle);
}
}
If I now have two child classes
public class Teacher extends Person{
public String jobTitle = "Teacher";
}
public class Janitor extends Person{
public String jobTitle = "Janitor";
}
and I want to avoid code cloning, i.e. implementing the same printJob()-method in both classes, I now have a problem, since the printJob()-method is unable to access member variables of the child classes.
Is there any way that i can call a parent classes' method but have the method use the child classes' member variables?
You can use abstract methods like this
public abstract class Person {
public void printJob() {
System.out.println(getJobTitle());
}
protected abstract String getJobTitle();
public static void main(String[] args) {
Person teacher = new Teacher();
Person janitor = new Janitor();
System.out.println(teacher.getJobTitle());
System.out.println(janitor.getJobTitle());
}
}
class Teacher extends Person {
#Override
protected String getJobTitle() {
return "Teacher";
}
}
class Janitor extends Person {
#Override
protected String getJobTitle() {
return "Janitor";
}
}
Updated after op's comment for code cloning...
public class Person {
public static void main(String[] args) {
System.out.println(new Teacher().job);
System.out.println(new Janitor().job);
}
private static class Teacher extends Person {
private String job = "Teacher";
}
private static class Janitor extends Person {
private String job = "Janitor";
}
}

extending an instantiation of a non-static class to a static class

I am trying to build a static class structure, and I want to convert an object instantiation of a non-static class to a static class of this static class structure, not as an object but as a class
I've tried things like
public final class Client {
public final static Widget FundSummary = new Widget("url")
{
public class FundSummary extends Widget{
public final static Field FUNDNAMELIST = new Field("xpath", this)
}
}
}
or
public final class Client {
public class FundSummary extends new Widget("xpath")//this is not the right syntax, but it's what I want to achieve
{
}
}
but havent been able to get my end goal of calling this static class using
Client.FundSummary.FUNDNAMELIST.getPermissions() //works
and
Client.FundSummary.getPermissions() //does not work
Here are the non-static classes
public class Element {
public final Integer id
public final String xpath
public final String nameUI
public Element(xpath, nameUI=null, id=null) {
this.xpath = xpath
this.id = id
this.nameUI = nameUI
}
}
public class Widget extends Element {
public final permissions
public Widget(xpath, nameUI=null, id=null, def permissions= null) {
super(xpath, nameUI, id)
this.permissions = permissions
}
public String getURL() {
}
public String getPermissions(User user, int entityID = GlobalVariable.clientID) {
}
}
public class Field extends Element{
public final Widget widget
public final permissions
public Field(xpath, Widget, nameUI=null, id=null, def permissions=null) {
super(xpath, nameUI, id)
this.permissions = permissions
this.widget = Widget
}
public String getPermissions(User user, int entityID = GlobalVariable.clientID) {
}
}

Java Interface containing an empty Enum

I'm trying to prepare an interface i want to implement for Datamodel-Classes.Therefor i want to use an enum inside the interface so i know i need to implement it later.
Example:
public interface MyModelInterface {
public enum Field;
public Object get(Field field);
public void set(Field field, Object value);
}
The expected implementation:
public class MyModel implements MyModelInterface {
public enum Field {
ID("id"),
Name1("Name1"),
Name2("Name2");
private String field;
private Field(String field) {
this.field = field;
}
}
public Object get(Field field) {
//...
}
public void set(Field field, Object value){
//...
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get(MyModel.Field.ID));
System.out.println(myModel.get(MyModel.Field.Name1));
}
}
Since I don't know which fields the model will contain until I implement it.
I did some research and figured that enum can't be extended, so i am aware of that.
is there any way to archive this or any kind of workaround?
i don't want to use String Parameters on the getter/setter Methods to avoid using wrong values.
Thanks in advance for any suggestion.
Update:
So this is what worked for me: Splitting the interface/class in three parts, including an abstract class:
Interface:
public interface MyModelInterface<E extends Enum<E>> {
public Object get(E field);
public void set(E field, Object value);
}
Abstract Class:
public abstract class MyAbstractModel<E extends Enum<E>> implements MyModelInterface<E>{
protected final EnumMap<E, Object> fields;
public MyAbstractModel(Class<E> enumKlazz) {
fields = new EnumMap<>(enumKlazz);
}
#Override
public Object get(E field) {
return fields.get(field);
}
#Override
public void set(E field, Object value) {
this.fields.put(field, value);
}
}
Class(where i actually archive my goal):
public class MyModel extends MyAbstractModel<MyModel.Field> {
public MyModel() {
super(MyModel.Field.class);
}
public enum Field {
ID("ID"),
Name1("NAME1"),
Name2("NAME2"),
Age("AGE"),
;
private final String field;
private Field(String field) {
this.field = field;
}
public String getName() {
return field;
}
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get(Field.Name1));
}
}
Interface fields are static and final implicitly.
What you could do is to have an interface method returning Enum<?>, and your classes implementing it.
For instance:
interface Foo {
public Enum<?> getEnum();
}
class Bar implements Foo {
enum Blah {
INSTANCE;
}
public Enum<?> getEnum() {
return Blah.INSTANCE;
}
}
Edit
Not completely sure I understand your question update, but here's a solution that will de-couple returning a specific enum instance from an enum, by means of two interfaces.
The example is self-contained in a Main class.
public class Main {
public static void main(String[] args) {
System.out.println(new Bar().getEnumField().name());
}
static interface IHasEnum {
public Enum<? extends IMyEnum> getEnumField();
}
static interface IMyEnum {
public Enum<? extends IMyEnum> getField();
}
static class Bar implements IHasEnum {
enum Blah implements IMyEnum {
DEFAULT_INSTANCE,
THE_FIELD;
public Enum<? extends IMyEnum> getField() {
return THE_FIELD;
}
}
public Enum<? extends IMyEnum> getEnumField() {
return Blah.DEFAULT_INSTANCE.getField();
}
}
}
Output
THE_FIELD
Note
The trick here is to add a "default" instance to the enum (DEFAULT_INSTANCE), so the getField method is an instance method, hence overriding the one declared in the IMyEnum interface.
Again, not entirely sure this addresses your issue.
What you are describing is an EnumMap<E, T> - which functions like an array, with that same get-
public class MyModelBase<E extends Enum<E>> {
private final Class<E> enumKlazz;
private final EnumMap<E, Object> fields;
public MyModelBase(Class<E> enumKlazz) {
this.enumKlazz = enumKlazz;
fields = new EnumMpa<>(enumKlazz);
}
public Object get(E field) {
return fields.get(field);
}
public void set(E field, Object value) {
fields.put(field, value);
}
}
enum UserField { id, surname, name, age };
MyModelBase<UserField> userModel = new MyModelBase<>(UserField.class);
userModel.set(UserField.surname, "X");
Because of type erasure the enum map needs the class. Above the enum class is also stored as field, as some static Enum methods need the enum class. For iterating, and so on.
Java generics will be the best solution.
Lets assume, you don't know the contents of the Field as mentioned.
Create a generic interface like this:
public interface MyModelInterface<T> {
public T get();
}
Then create a class Field like this:
public class Field {
private String id;
private String name1;
private String name2;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName1() {
return name1;
}
public void setName1(String name1) {
this.name1 = name1;
}
public String getName2() {
return name2;
}
public void setName2(String name2) {
this.name2 = name2;
}
}
and then your model class will look like
public class MyModel implements MyModelInterface<Field> {
#Override
public Field get() {
Field field = new Field();
field.setId("ID");
field.setName1("Name1");
field.setName2("Name2");
return field;
}
public static void main(String[] args) {
MyModel myModel = new MyModel();
System.out.println(myModel.get().getId());
System.out.println(myModel.get().getName1());
System.out.println(myModel.get().getName2());
}
}

Target Unreachable, 'current' returned null - AbstractFactory

I'm trying to access an object inside a managed bean, which implements AbstractMB. Any property accessed by a page has error "Unknown property". When I try to insert it in the database,through a commandButton, PropertyNotFoundException is thrown.
AbstractMB relevant code:
public abstract class AbstractMB<T> implements Serializable {
private Class<T> type;
private AbstractDAO<T> typeDAO;
private T current;
private List<T> elements = new ArrayList();
protected T object = this.getCurrent();
protected List<T> list = this.getElements();
public abstract void save(ActionEvent actionEvent);
public AbstractMB() {}
public AbstractMB(Class<T> type) {
super();
this.type = type;
}
public T getCurrent() {
return current;
}
public void setCurrent(T current) {
this.current = current;
}
}
Full FonteMB class:
#Named
#RequestScoped
public class FonteMB extends AbstractMB<Fonte> {
public FonteMB() {
super(Fonte.class);
}
#Override
public void save(ActionEvent actionEvent) {
if(this.object.getCodigo() == null) {
this.getTypeDAO().add(this.object);
} else {
this.getTypeDAO().edit(this.object);
}
this.object = new Fonte();
this.list = null;
}
}
Class Fonte from the model package implements java.io.Serializable, all getter and setter, hashCode and equals methods. And toString returning the class name ("Fonte").
Also tried to use a converter, but result was the same.
What I'm missing?

Categories