I have been trying to code an app but I am stuck with a problem. I have a function checkexistence which checks weather column with column name as the current month is present or not and another function that inserts rows in the sql database but I am not able to figure out how can use both of them to check that weather current month is present or not and if not add the current month
Here is the class with the code.
public class Repository {
private MonthDetailsDAO monthDetailsDAO;
private static Repository instance;
private YearDetailsDAO yearDetailsDAO;
private LiveData<List<MonthDetailsEntity>> liveMonthData;
private LiveData<List<YearDetailsEntity>> liveYearData;
private static final String LOG_TAG = "Database>>Repository";
public Repository(Application application){
Database database = Database.getInstance(application);
yearDetailsDAO = database.yearDetailsDAO();
liveYearData = yearDetailsDAO.getdata();
}
public void add_year(YearDetailsEntity yearDetailsEntity){
new InsertAsyncTask(yearDetailsDAO).execute(yearDetailsEntity);
}
public void checkExistance(YearDetailsEntity yearDetailsEntity){
new CheckExistanceAsyncTask(yearDetailsDAO).equals(yearDetailsEntity);
}
public LiveData<List<YearDetailsEntity>> getLiveYearData(){
return liveYearData;
}
private static class CheckExistanceAsyncTask extends AsyncTask<YearDetailsEntity , Void , Void>{
private YearDetailsDAO yearDetailsDAO;
public CheckExistanceAsyncTask(YearDetailsDAO yearDetailsDAO){
this.yearDetailsDAO = yearDetailsDAO;
}
#Override
protected Void doInBackground(YearDetailsEntity... yearDetailsEntities) {
int m = yearDetailsEntities[0].getMonth();
int y = yearDetailsEntities[0].getYear();
YearDetailsEntity yearDetailsEntity1 = yearDetailsDAO.checkExistance(m , y);
if(yearDetailsEntity1 == null) {
//insert now
}
else
Log.d(LOG_TAG , "Month already present");
return null;
}
}
private static class InsertAsyncTask extends AsyncTask<YearDetailsEntity, Void, Void> {
private YearDetailsDAO yearDetailsDAO;
public InsertAsyncTask(YearDetailsDAO yearDetailsDAO){
this.yearDetailsDAO = yearDetailsDAO;
}
#Override
protected Void doInBackground(YearDetailsEntity... yearDetailsEntities) {
yearDetailsDAO.add_year(yearDetailsEntities[0]);
return null;
}
}
}
Related
I've tried using the below code to load some data from my database and display them in an activity:
PhoneNumberViewModel phoneNumberViewModel =
new ViewModelProvider(WorksideContactCard.this).get(PhoneNumberViewModel.class);
phoneNumberViewModel
.getPhoneNumbersById(contactID)
.observe(this,
numbers -> {
phoneNumberList = numbers;
});
To be precise, I needn't observe the data changing, as the data will be refreshed if the activity is resumed. But the above code freezes my application, although I am accessing the DB using an AsyncTask in my other class.
Why could this be so?
EDIT:
PhoneNumberViewModel.class:
public class PhoneNumberViewModel extends AndroidViewModel {
private PhoneNumberRepository phoneNumberRepository;
private LiveData<List<PhoneNumber>> allPhoneNumbers;
public PhoneNumberViewModel(#NonNull Application application) {
super(application);
phoneNumberRepository = new PhoneNumberRepository(application);
allPhoneNumbers = phoneNumberRepository.getAllPhoneNumbersLive();
}
public void insert(PhoneNumber phoneNumber) {
System.out.println("[PhoneNumberRepository] Adding new phoneNumber");
phoneNumberRepository.insert(phoneNumber);
}
public void update(PhoneNumber phoneNumber) {
phoneNumberRepository.update(phoneNumber);
}
public void delete(PhoneNumber phoneNumber) {
phoneNumberRepository.delete(phoneNumber);
}
public LiveData<List<PhoneNumber>> getAllPhoneNumbers() {
return allPhoneNumbers;
}
public LiveData<List<PhoneNumber>> getPhoneNumbersById(long contactId)
throws ExecutionException, InterruptedException {
return phoneNumberRepository.getPhoneNumbersByContactId(contactId);
}
PhoneNumberRepository.class
public class PhoneNumberRepository {
private PhoneNumberDao phoneNumberDao;
private LiveData<List<PhoneNumber>> allPhoneNumbers;
private LiveData<List<PhoneNumber>> phoneNumbersByIdList;
public PhoneNumberRepository(Application application) {
WorksideDatabase database = WorksideDatabase.getInstance(application);
phoneNumberDao = database.phoneNumberDao();
allPhoneNumbers = phoneNumberDao.getAllPhoneNumbers();
}
...
public LiveData<List<PhoneNumber>> getAllPhoneNumbersLive() {
return allPhoneNumbers;
}
public void deleteAllPhoneNumbers() {
new DeleteAllPhoneNumbersAsyncTask(phoneNumberDao).execute();
}
public LiveData<List<PhoneNumber>> getPhoneNumbersByContactId(long id)
throws ExecutionException, InterruptedException {
return new SelectPhoneNumberByIdAsyncTask(phoneNumberDao, id).get();
}
private static class SelectPhoneNumberByIdAsyncTask
extends AsyncTask<Long, Void, LiveData<List<PhoneNumber>>> {
private PhoneNumberDao phoneNumberDao;
private Long ID;
private SelectPhoneNumberByIdAsyncTask(PhoneNumberDao phoneNumberDao, Long contactId) {
this.phoneNumberDao = phoneNumberDao;
ID = contactId;
}
#Override
protected LiveData<List<PhoneNumber>> doInBackground(Long... contactId) {
ID = contactId[0];
return phoneNumberDao.getPhoneNumbersById(ID);
}
}
...
}
PhoneNumberDao.class:
#Dao
public interface PhoneNumberDao {
#Insert
void insert(PhoneNumber phoneNumber);
#Update
void update(PhoneNumber phoneNumber);
#Delete
void delete(PhoneNumber phoneNumber);
// Probably uneeded method
#Query("DELETE FROM phone_numbers_table")
void deleteAllPhoneNumbers();
// Delete entry/entries by ID
#Query("DELETE FROM phone_numbers_table WHERE id = :phoneNumberId")
void deleteByPhoneNumberId(long phoneNumberId);
// Retrieve entry/entries by contact ID
// #Query("SELECT * FROM phone_numbers_table WHERE contact_id = :contactId")
// List<PhoneNumber> getPhoneNumbersById(long contactId);
// Retrieve all saved phone numbers in LiveData format
#Query("SELECT * FROM phone_numbers_table")
LiveData<List<PhoneNumber>> getAllPhoneNumbers();
#Query("SELECT * FROM phone_numbers_table WHERE contact_id = :contactId")
LiveData<List<PhoneNumber>> getPhoneNumbersById(long contactId);
#Query("SELECT * FROM phone_numbers_table")
List<PhoneNumber> getAll();
}
return new SelectPhoneNumberByIdAsyncTask(phoneNumberDao, id).get();
this here is your problem ,.get() call blocks the main thread
I would suggest switching to Kotlin and using Coroutines or here you can handle this using callbacks and not using AsyncTask.get() which blocks the main thread.Also BTW Async Task is going to be deprecated last I heard ,So keep that in mind too.
This is one solution the problem
public class Repository implements
SelectPhoneNumberByIdAsyncTask.OnPhoneNumberFound {
#Override
public void onPhoneNumberFound(LiveData<List<Object>> list) {
//you can get the data you want here
}
}
class SelectPhoneNumberByIdAsyncTask extends AsyncTask<Long, Void,
LiveData<List<PhoneNumber//Correct this>>> {
interface OnPhoneNumberFound{
void onPhoneNumberFound(LiveData<List<PhoneNumberDao>> list);
}
OnPhoneNumberFound mListener;
private PhoneNumberDao phoneNumberDao;
private Long ID;
private SelectPhoneNumberByIdAsyncTask(Object phoneNumberDao, Long contactId) {
this.phoneNumberDao = phoneNumberDao;
ID = contactId;
}
#Override
protected LiveData<List<Object>> doInBackground(Long... contactId) {
ID = contactId[0];
mListener.onPhoneNumberFound(phoneNumberDao.getPhoneNumbersById(ID));
return null;
}
}
use .execute() call now instead of .get()
I am trying to simplify the number of lines for my codes in the repository.
Currently there is a lot of repetition in my codes.
Many of the solutions online only involves inserting once into the table.
I need to do insert() on many tables. I want to reduce the repetition for writing the same inner AsyncTask for inserting different data into different table
This is the codes for the repository class
public class CharacterRepository {
private UserDao rUserDao;
private CharacterDao rCharacterDao;
private EquipementDao rEquipementDao;
private LiveData<List<UserDao>> rUserLD;
private LiveData<List<CharacterDao>> rCharacterLD;
private LiveData<List<EquipmentDao>> rEquipmentLD;
// Constructor that handles the database and initialise the member variables
CharacterRepository(Application application){
MyDatabase db = MyDatabase.getDatabase(application);
rUserDao = db.userDao();
rCharacterDao = db.characterDao();
rEquipementDao = db.EquipmentDao();
rUserLD = rUserDao.getAllUser();
rCharacterLD = rCharacterDao.getAllChar();
rEquipmentLD = rEquipementDao.getAllEquip();
}
// Wrapper method that returns cached entities as LiveData
public LiveData<List<UserEntity>> getAllUser(){return rUserLD;}
public LiveData<List<CharEntity>> getAllChar(){return rCharacterLD;}
public LiveData<List<EquipEntity>> getAllEquip(){return rEquipmentLD;}
/*---------------------the start of the problem-------------------*/
//Wrapper method: calling insert on non-UI Thread
public void insert(UserEntity userEntity){new insertUserAsyncTask(rUserDao).execute(userEntity);}
public void insert(CharacterEntity characterEntity){new insertCharacterAsyncTask(rCharacterDao).execute(characterEntity);}
public void insert(EquipmentEntity equipmentEntity){new insertEquipAsyncTask(rCharacterDao).execute(equipmentEntity);}
/*-------------------THIS IS THE PART WHERE I WANT TO REDUCE THE CODE REDUNDANCY THE CODES ARE DOING THE SAME THING-------------------*/
private static class insertUserAsyncTask extends AsyncTask<UserEntity, Void, Void> {
private UserDao mAsyncTaskDao;
insertUserAsyncTask(UserDao dao) {mAsyncTaskDao = dao;}
#Override
protected Void doInBackground(UserEntity... userEntities) {
mAsyncTaskDao.save(params[0]);
return null;
}
}
private static class insertCharacterAsyncTask extends AsyncTask<CharacterEntity, Void, Void> {
private CharacterDao mAsyncTaskDao;
insertCharacterAsyncTask(CharacterDao dao) {mAsyncTaskDao = dao; }
#Override
protected Void doInBackground(CharacterEntity... characterEntities) {
mAsyncTaskDao.save(params[0]);
return null;
}
}
private static class insertEquipAsyncTask extends AsyncTask<, Void, Void> {
private EquipmentDao mAsyncTaskDao;
insertEquipAsyncTask(EquipmentDao dao) {mAsyncTaskDao = dao;}
#Override
protected Void doInBackground(EquipmentEntity... equipmentEntities) {
mAsyncTaskDao.save(params[0]);
return null;
}
}
}
I still have other insert methods and I need to call delete and update as well. I do not want the codes to so repetitive
so, #notTdar came up with this solution
Have a class call ThreadPoolExecutor.
Call this class to execute all the DAO from the Android Room Database
Call cleanResource(); in onDestroy
Call shut(); in onPause
ThreadPoolExecutorHelper.java
public class ThreadPoolExecutorHelper {
private static final String TAG = ThreadPoolExecutorHelper.class.getSimpleName() + " : ";
private static final boolean LOG_DEBUG = false;
private static volatile ThreadPoolExecutorHelper INSTANCE;
private ThreadPoolExecutor mThreadPoolExecutor;
private BlockingQueue<Runnable> mBlockingQueue;
private static final int TASK_QUEUE_SIZE = 12;
//core size, keeps thread : along with running + idle
private static final int CORE_POOL_SIZE = 5;
// pool size
private static final int MAX_POOL_SIZE = 5;
// core pool size exceeds, idle thread will wait for this time before termination.
private static final long KEEP_ALIVE_TIME = 20L;
public static ThreadPoolExecutorHelper getInstance() {
if (LOG_DEBUG) Log.e(TAG, "getInstance: ");
if (INSTANCE == null) {
synchronized (ThreadPoolExecutorHelper.class) {
if (INSTANCE == null) {
INSTANCE = new ThreadPoolExecutorHelper();
}
}
}
return INSTANCE;
}
private ThreadPoolExecutorHelper() {
if (LOG_DEBUG) Log.d(TAG, "ctor: ");
initBlockingQueue();
initThreadPoolExecutor();
}
// submit Runnables
public void submitRunnable(Runnable task) {
if (LOG_DEBUG) Log.d(TAG, "submitRunnable: " + task.getClass().getSimpleName());
//in case, init again, if null.
initBlockingQueue();
initThreadPoolExecutor();
mThreadPoolExecutor.execute(task);
}
// shut the threadpool
public synchronized void shut() {
if (LOG_DEBUG) Log.d(TAG, "shut: ");
if (mThreadPoolExecutor != null) {
mThreadPoolExecutor.shutdown();
try {
mThreadPoolExecutor.awaitTermination(6000L, TimeUnit.SECONDS);
} catch (InterruptedException e) {
if (LOG_DEBUG) Log.w(TAG, "shut: InterruptedException");
mThreadPoolExecutor.shutdownNow();
}
} else {
Log.e(TAG, "shut: mThreadPoolExecutor instance NULL");
}
}
//clean up
public void cleanResources() {
if (LOG_DEBUG) Log.e(TAG, "cleanResources: ");
if (INSTANCE != null) {
if (mThreadPoolExecutor != null) {
mThreadPoolExecutor = null;
}
if (mBlockingQueue != null) {
mBlockingQueue = null;
}
nullifyHelper();
}
}
private static void nullifyHelper() {
if (INSTANCE != null) {
INSTANCE = null;
}
}
private void initBlockingQueue() {
if (mBlockingQueue == null) {
mBlockingQueue = new LinkedBlockingQueue<>(TASK_QUEUE_SIZE);
}
}
private void initThreadPoolExecutor() {
if (mThreadPoolExecutor == null) {
mThreadPoolExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE,
KEEP_ALIVE_TIME, TimeUnit.SECONDS, mBlockingQueue);
}
}
}
Add this codes in onCreate (activity) or onViewCreated(Fragment)
This will initialise the ThreadPoolExecutorHelper by calling getInstance()
private void initExecutorHelper() {
if (LOG_DEBUG) Log.d(TAG, "initExecutorHelper: ");
if (mExecutorHelper == null) {
mExecutorHelper = ThreadPoolExecutorHelper.getInstance();
}
}
This is the insert(); method to start a Thread
You can change this to do insert, query, delete task from the DAO in Room Database
public void insert() {
if (LOG_DEBUG) Log.d(TAG, "requestQREntityList: whatKind= " + whatKind);
mExecutorHelper.submitRunnable(() -> {
if (!Thread.interrupted()) {
//request a list or inset something, write your logic.
} else {
if (LOG_DEBUG) Log.e(TAG, "run: Thread is interrupted");
}
});
}
I have an online quiz app in Firebase. Shuffle method does not work. Every time question come the same interval.
Each time the questions come the same. Comes with the same sequence. I do not understand why that happens.
The question is actually very simple, but I have to extend it for acceptance.
private void loadQuestions(String categoryId) {
//First, clear list if have old questions
if (Common.questionList.size()>0)
Common.questionList.clear();
question.orderByChild("categoryId").equalTo(categoryId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Question question = postSnapshot.getValue(Question.class);
Common.questionList.add(question);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {}
});
//Random list
Collections.shuffle(Common.questionList);
}
public class Question {
private String sul, bri, ki, cu, dor, du, categoryId, sek;
public Question() {
}
public Question(String sul, String bri, String ki, String cu, String dor, String du, String categoryId, String sek) {
this.sul = sul;
this.bri = bri;
this.ki = ki;
this.cu = cu;
this.dor = dor;
this.du = du;
this.categoryId = categoryId;
this.sek = sek;
}
public String getSul() {
return sul;
}
public void setSul(String sul) {
this.sul = sul;
}
public String getBri() {
return bri;
}
public void setBri(String bri) {
this.bri = bri;
}
public String getKi() {
return ki;
}
public void setKi(String ki) {
this.ki = ki;
}
public String getCu() {
return cu;
}
public void setCu(String cu) {
this.cu = cu;
}
public String getDor() {
return dor;
}
public void setDor(String dor) {
this.dor = dor;
}
public String getDu() {
return du;
}
public void setDu(String du) {
this.du = du;
}
public String getCategoryId() {
return categoryId;
}
public void setCategoryId(String categoryId) {
this.categoryId = categoryId;
}
public String getSek() {
return sek;
}
public void setSek(String sek) {
this.sek = sek;
}
}
public class Common {
public static String categoryId,categoryName;
public static User currentUser;
public static List<Question> questionList = new ArrayList<>();
public static final String STR_PUSH = "pushNotification";
}
When you using the following line of code:
Collections.shuffle(Common.questionList);
Outside the onDataChange(), it means that you are trying to shuffle an empty list. This is happening because this method has an asynchronous behavior which means that by the time you are trying to shuffle that list outside that method, the data hasn't finished loading yet from the database and that's why is not accessible.
A quick solve for this problem would be to move that line of code inside the onDataChange() method, otherwise I recommend you see the last part of my anwser from this post in which I have explained how you can use a String (it can be any other object, even a List) outside the onDataChange() method using a custom callback. You can also take a look at this video for a better understanding.
I have two classes:
public class UnoLoginPageUi {
public final Input username = new Input("id=username");
public final Input password = new Input("id=password");
public final Button loginButton = new Button("name=login");
}
and
public class DuoLoginPageUi {
public final Input username = new Input("id=usernameField");
public final Input password = new Input("id=passwordField");
public final Button loginButton = new Button("id=submitButton");
}
and in one common class I want to make something like that:
public void loginUsingUsernameAndPassword(String username, String password, String pageType) {
getUi(pageType).username.waitForToBeDisplayed();
getUi(pageType).username.setValue(username);
getUi(pageType).password.setValue(password);
getUi(pageType).loginButton.click();
}
where getUi() is a method that gas argument pageType (which is UNO or DUO).
private Class getUi(String pageType) {
if (pageType.equals("UNO")) {
return new DuoLoginPageUi();
}
else if (pageType.equals("DUO")) {
return new UnoLoginPageUi;
}
return null;
}
However it doesn't work as this method need to in type of this two pages with selectors - how to deal with that ?
You can create a interface called LoginPageUi. And let your UnoLoginPageUi and DuoLoginPageUi implement that interface.
Then your getUi method will be private LoginPageUi getUi(String pageType).
Off topic: I would recommend to implement an enum instead of String pageType.
Create a common abstraction for the two classes
public abstract class LoginPageUi {
public final Input username = new Input("id=username");
public final Input password = new Input("id=password");
public final Button loginButton = new Button("name=login");
}
and have UnoLoginPageUi and DuoLoginPageUi extend that
public class UnoLoginPageUi extends LoginPageUi {
public static String getPageType() { return "UNO"; }
}
public class DuoLoginPageUi extends LoginPageUi {
public static String getPageType() { return "DUO"; }
}
The method would return the common abstraction
private LoginPageUi getUi(String pageType) {
if (pageType.equals(DuoLoginPageUi.getPageType())) {
return new DuoLoginPageUi();
}
else if (pageType.equals(UnoLoginPageUi.getPageType())) {
return new UnoLoginPageUi;
}
return null;
}
I also hope you realize that every time you call getUi(pageType) it is returning a new instance. by the time you call getUi(pageType).loginButton.click(); the instance returned has no values set.
Refactor:
public void loginUsingUsernameAndPassword(String username, String password, String pageType) {
LoginPageUi ui = getUi(pageType);
if (ui != null) {
ui.username.waitForToBeDisplayed();
ui.username.setValue(username);
ui.password.setValue(password);
ui.loginButton.click();
}
}
create Parent class or interface for both called UI:
public abstract class Ui{
}
public interface Ui{
}
and extend it:
public class UnoLoginPageUi extends Ui{
public final Input username = new Input("id=username");
public final Input password = new Input("id=password");
public final Button loginButton = new Button("name=login");
}
public class DuoLoginPageUi extends Ui {
public final Input username = new Input("id=usernameField");
public final Input password = new Input("id=passwordField");
public final Button loginButton = new Button("id=submitButton");
}
or
public class UnoLoginPageUi implements Ui{
public final Input username = new Input("id=username");
public final Input password = new Input("id=password");
public final Button loginButton = new Button("name=login");
}
public class DuoLoginPageUi implements Ui {
public final Input username = new Input("id=usernameField");
public final Input password = new Input("id=passwordField");
public final Button loginButton = new Button("id=submitButton");
}
then return parent reference as:
private Ui getUi(String pageType) {
if (pageType.equals("UNO")) {
return new DuoLoginPageUi();
}
else if (pageType.equals("DUO")) {
return new UnoLoginPageUi;
}
return null;
}
I have no problem filling my tableview with diffrent data from 1 class. But it does not work for me with multiple classes. Any idea how to solve that?
I have checked out similar questions on stackoverflow. But none of them could help me. If you suggest anything with the "Callback" class, please provide me the full import, because there are a couple of Callback classes out there.
public class MainViewController implements Initializable {
#FXML
private TableColumn<TaskControl, Boolean> colErledigt;
#FXML
private TableColumn<TaskControl, Character> colPrioritaet;
#FXML
private TableColumn<TaskControl, String> colBeschreibung;
#FXML
private TableColumn<ProjectControl, String> colProjekt;
#FXML
private TableView<TaskControl> tblView;
public final void initialize(final URL location,
final ResourceBundle resources) {
initializeTableElements();
}
public final void initializeTableElements() {
colBeschreibung
.setCellValueFactory(new PropertyValueFactory<>("description"));
colPrioritaet
.setCellValueFactory(new PropertyValueFactory<>("priority"));
colProjekt.setCellValueFactory(new PropertyValueFactory<>("name"));
colErledigt.setMaxWidth(50);
colErledigt.setCellValueFactory(
new PropertyValueFactory<TaskControl, Boolean>("isDone"));
colErledigt
.setCellFactory(CheckBoxTableCell.forTableColumn(colErledigt));
colErledigt.setEditable(true);
try {
tblView.setItems(getObsTasks());
} catch (IDNotValidException | StringNotValidException e1) {
System.out.print("FEHLER beim getObsTasks");
}
tblView.setEditable(true);
}
public ObservableList<TaskControl> getObsTasks()
throws IDNotValidException, StringNotValidException {
ObservableList<TaskControl> obsTasks = FXCollections
.observableArrayList();
Map<Context, Set<Task>> test = TasksContextUtility.INSTANCE
.getAllContextsAndTasks();
test.values().forEach(v -> {
v.forEach(b -> obsTasks.add((TaskControl) b));
});
return obsTasks;
}
Further question: How can I show a certain Attribute of an Instance in a HashSet in a TableCell. So I have in my TaskControl class a HashSet. In that HashSet there are Instances of the class "ProjectControl". Every instance of ProjectControl has attributes like "name" or "id" etc.
And I want to represent all the names of the project instances in 1 single table cell if possible. Maybe as a string seperated with commas (project1,project2,project3...).
Task class (shortened a lot) my TaskControl Class inherits from this class
public abstract class Task
implements Serializable, IDValidatable
{
private int id;
private char priority = ' ';
private final Set<Project> projects = new HashSet();
public Task(int oid)
throws IDNotValidException
{
if (isIDValid(oid)) {
this.id = oid;
} else {
throw new IDNotValidException("The ID you have specified is not valid!")
{
private static final long serialVersionUID = 99044660889990790L;
};
}
}
public final void setId(int oid)
throws IDNotValidException
{
if (isIDValid(oid)) {
this.id = oid;
} else {
throw new IDNotValidException("The ID you have specified is not valid!")
{
private static final long serialVersionUID = 99044660889990790L;
};
}
}
public final int getId()
{
return this.id;
}
public final Collection<Context> getContexts()
{
return this.contexts;
}
public final void addContext(Context context)
throws ContextNotValidException
{
this.contexts.add(context);
}
public final void removeContext(Context context)
throws ContextNotValidException
{
this.contexts.remove(context);
}
public final Collection<Project> getProjects()
{
return this.projects;
}
public final void addProject(Project project)
throws ProjectNotValidException
{
this.projects.add(project);
}
public final void removeProject(Project project)
throws ProjectNotValidException
{
this.projects.remove(project);
}
public final Map<String, String> getAddons()
{
return this.addons;
}
}
In my opition you only have one nice solution for this.
You need a extra Class that holds your TaskControl, ContextControl and ProjectControl.
Your Code can look something like that.
class Wrapper{
private TaskControl taskControl;
private ContextControl contextControl;
private ProjectControl projectControl;
...
public Boolean isDone(){
return taskControl != null ? taskControl.isDone() : null;
}
}
#FXML
private TableView<Wrapper> tblView;
#FXML
private TableColumn<Wrapper, Boolean> colErledigt;
colErledigt.setCellValueFactory(
new PropertyValueFactory<Wrapper, Boolean>("isDone"));
Solved it by adding an additional String to my TaskControl, that contains the names of all the projects it contains. It gets the names through a function that I call just before I create the ObservableList for the Table Column.
private String projectsAsString;
...
public final void convertProjectsToString() {
String projects = "";
for (Project p : this.getProjects()) {
ProjectControl pp = (ProjectControl) p;
projects += pp.getName() + ", ";
}
if (projects != null && projects != "" && projects.length() > 4) {
projects = projects.substring(0, projects.length() - 2);
}
this.projectsAsString = projects;
}
Thank you guys anyways for helping me.