Getter method returns null. Java MVC - java

I have googled for a whole day but I just can't find an answer to my problem.
I'm using the MVC pattern.
Basically I have a list of songs (id, title, author, ect.) that I need to display in a JTable. The songs are stored in a MySQL database.The Connection to database works fine.
I'm currently storing all the reconds from my database in an 'ArrayList'
This is what I have so far:
The code to store the songs:
SongDAO songDAO = new SongDAO();
ArrayList<Song> songs = songDAO.findAll();
When printing out the songs, I get this output:
[oop.model.entities.Song#1055e4af, oop.model.entities.Song#3caeaf62, oop.model.entities.Song#e6ea0c6, oop.model.entities.Song#6a38e57f]
This is where I play the first song:
if (songs.isEmpty()) {
library = null;
} else {
library = songs.get(0);
Mainframe.setVisible(true);
firstController();
}
public static Library getLibrary() {
return library;
}
The library static factory method:
public static void firstController() {
new libraryController(view.libraryView);
}
I'm pretty sure the problem is here. I just can't figure it out for the life of me.
public class libraryController {
private libraryView view;
public libraryController(libraryView view) {
this.view = view;
for (Song song : baseController.getLibrary().getSongs()) {
view.addSong(song);
}
updateView();
}
public void updateView() {
view.setSongs(baseController.getLibrary().getSongs());
}
}
I've tried System.out.println(baseController.getLibrary().getSongs()), but all i get is [ ]. This leads me to believe the getSongs() method is the cause.
public void setSongs(ArrayList<Song> songs) {
for (Song song : songs) {
addSong(Song);
}
}
public void addSong(Song song) {
Object[] row = new Object[]{song.getId(), song.getTitle(), song.getArtist(), song.getAlbum(), song.getGenre(), song.getYear()};
model.addRow(row);
}
Here is my Library Class:
public class Library {
private ArrayList<Song> songs;
private int id;
private Song song;
public Library() {
id=0;
songs = new ArrayList<Song>(20);
}
public ArrayList<Song> getSongs() {
return songs;
}
public Libreria setSongs(ArrayList<Song> songs) {
this.songs = songs;
return this;
}
}
My song class:
public class Song extends Library {
private int id;
private String title;
private String artist;
private String album;
private String genre;
private int year;
private Library library;
public Song(){
id = 0;
}
public int getId() {return id; }
public void setId(int id) {this.id = id;}
public String getTitle() { return title;}
public void setTitle(String title) {this.title = title;}
public String getArtist() { return artist;}
public void setArtist(String artist) {this.artist = artist;}
public String getAlbum() {return album;}
public void setAlbum(String album) {this.album = album; }
public String getGenre() {return genre;}
public void setGenre(String genre) {this.genre = genre;}
public int getYear() {return year;}
public void setYear(int year) {this.year = year;}
public Library getLibrary() {return library;}
public Song setLibrary(Library library) {
this.library = library;
return this;
}
}
If anyone could help me, that would be greatly appreciated.

Basically i have to display in JTable my songs ('id','title,'author','..')
Swing components are already designed using a modified version of MVC.
If you want to display data in a JTable you just need to load the data into a TableModel.
So you may want to create a custom TableModel so hold your Song objects.
Check out Table Row Model.
It shows you step by step how to create a custom model for the Song object. Or if you want you can use the generic TableRowModel to make the coding easier.
Once you create the SongTableModel the code to use it would be something like:
SongTableModel model = new SongTableModel( songs );
JTable table = new JTable( model );

Related

Reorder Recyclerview items with custom adapter

I have a problem that many people had but i don't understand how can i get out of it.
Please help me in my case and do not mark as duplicated.
I have a recyclerview linked with firebase.
My recyclerview has a custom adapter called MyAdapter:
public class MyAdapter extends RecyclerView.Adapter<MyHolder> implements Filterable {
Context c;
ArrayList<Studi> studi;
ArrayList<Studi> filterList;
CustomFilter filter;
public MyAdapter(Context c, ArrayList<Studi> studi) {
this.c = c;
this.studi = studi;
this.filterList = studi;
}
#Override
public MyHolder onCreateViewHolder (ViewGroup parent, int viewType){
View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.model, parent, false);
MyHolder holder = new MyHolder(v);
return holder;
}
#Override
public void onBindViewHolder (MyHolder holder, int position){
String name = studi.get(position).getName();
String desc = studi.get(position).getDescription();
String prof = studi.get(position).getProfessione();
String tel = studi.get(position).getTelefono();
String coord1 = studi.get(position).getCoordinata1();
String coord2 = studi.get(position).getCoordinata2();
String distanza = studi.get(position).getDistanza();
holder.nameTxt.setText(name);
holder.descTxt.setText(desc);
holder.profTxt.setText(prof);
holder.telTxt.setText(tel);
holder.pos1Txt.setText(coord1);
holder.pos2Txt.setText(coord2);
holder.distanza.setText(distanza);
}
#Override
public int getItemCount (){
return (studi == null) ? 0 : studi.size();
}
//FILTER THING......................
public Filter getFilter() {
if(filter == null)
{
filter=new CustomFilter(filterList,this);
}
return filter;
}}
All the items have got a textview inside where it is written the String Distanza. This string is a number for each recyclerview item.
I need to reorder all the recyclerview items from the lower to the higher (Value of the String Distanza).
This is my Studi class which i use for the arraylist:
public class Studi {
private String name;
private String description;
private String professione;
private String telefono;
private String coordinata1;
private String coordinata2;
private String distanza;
public void setDistanza(String distanza) {
this.distanza = distanza;
}
public String getDistanza() {
return distanza;
}
public String getCoordinata2() {
return coordinata2;
}
public void setCoordinata2(String coordinata2) {
this.coordinata2 = coordinata2;
}
public String getCoordinata1() {
return coordinata1;
}
public void setCoordinata1(String coordinata1) {
this.coordinata1 = coordinata1;
}
public String getProfessione() {
return professione;
}
public void setProfessione(String professione) {
this.professione = professione;
}
public String getTelefono() {
return telefono;
}
public void setTelefono(String telefono) {
this.telefono = telefono;
}
public Studi() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}}
So at the end, i need to reorder them at the top of the recyclerview from the ones that return a getDistanza() value lower than the others.
How can i do it? I have really no idea, and sorry but i am new at this.
You can sort your data before passing it to MyAdapter. You can use the sort method from the Collections class. You would have something like this:
Collections.sort(studi, new Comparator<Studi>() {
public int compare(Studi s1, Studi s2) {
return s1.getDistanza() - s2.getDistanza();
}
})
At the end, whenever you filter your data, it always will respect the getDistanza sorting.
You should not sort your data while you are inflating your recyclerView. Infact now that you are already fetching your data from firebase-database, you should use your query accordingly to get the result in sorted form.
If you want your list to be in increasing order of distance (distanza in your case), just use a query something like this
const query = itemsRef.orderByChild('distanza');
This will give you a sorted array which you dont need to sort anymore.
P.S. If you want your recyclerView to have changes in real-time, do not use your custom adapter, instead use the firebaseRecyclerviewAdapter.

How i can design these with abstract class

When i want to add item to favorite .. i write this code my program and access everywhere: Favorite.add(itemid);
When i want to add item to message i write this code my program and access everywhere: Message.add(itemid);
Two class have some methods. So how i can design this useful?
For example;
AbstractData.addFavorite(itemid);
AbstractData.addMessage(itemid);
or
AbstractData<Fav>.add(itemid);
AbstractData<SMS>.add(itemid);
or
Your opinion?
Thank for help and sory for my little english...
Favorite.class
public class Favorite {
static SparseArray<Fav> LIST = new SparseArray<>();
public static boolean add(int ID){
if(!check(ID)){
LIST.put(ID, new Fav(ID, DateFormat.getDateTimeInstance().format(new Date())));
return true;
}
return false;
}
public static void remove(int ID){
if(LIST.indexOfKey(ID) >= 0 )
LIST.remove(ID);
}
public static boolean check(int ID){return LIST.get(ID) != null;}
public static Fav get(int ID){return LIST.get(ID);}
public static void saveALL(){
AsyncTask.execute(new Runnable() {
#Override
public void run() {
Fav favorite;
for (int i = 0; i < LISTE.size(); i++) {
favorite = get(LISTE.keyAt(i));
if (favorite != null)
//Saving data to xml
}
}
});
Log.d("DONE", "Favorite LIST Saving");
}
}
Fav.class
public class Fav implements IModel{
private int ID;
private String DATE;
public Fav(int ID, String DATE) {
this.ID = ID;
this.DATE = DATE;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getDate() {
return DATE;
}
public void setDate(String DATE) {
this.DATE = DATE;
}
}
Message.class
public class Message{
static SparseArray<SMS> LIST = new SparseArray<>();
public static boolean add(int ID){
if(!check(ID)){
LIST.put(ID, new SMS(ID, DateFormat.getDateTimeInstance().format(new Date())));
return true;
}
return false;
}
public static void remove(int ID){
if(LIST.indexOfKey(ID) >= 0 )
LIST.remove(ID);
}
public static boolean check(int ID){return LIST.get(ID) != null;}
public static SMS get(int ID){return LIST.get(ID);}
public static void saveALL(){
AsyncTask.execute(new Runnable() {
#Override
public void run() {
SMS message;
for (int i = 0; i < LISTE.size(); i++) {
message = get(LISTE.keyAt(i));
if (message != null)
//Saving data to xml
}
}
});
Log.d("DONE", "Message LIST Saving");
}
}
SMS.class
public class SMS implements IModel{
private int ID;
private String DATE;
public SMS(int ID, String DATE) {
this.ID = ID;
this.DATE = DATE;
}
public int getID() {
return ID;
}
public void setID(int ID) {
this.ID = ID;
}
public String getDate() {
return DATE;
}
public void setDate(String DATE) {
this.DATE = DATE;
}
}
IModel.class
public interface IModel {
int getID();
void setID(int ID);
String getDate();
void setDate(String DATE);
}
In my opinion...
Don't over-design your models.
Don't make your add and remove methods static, it will eventually leave you with headaches. You want your constructor to initialize your object.
Either use a Singleton Pattern to get a single instance of your manager object, or
Keep your manager class as a local variable in your Application class, make an access method for it, initialize it in onCreate().
Personally I've started to ditch the getter/setter pattern in favour of public fields, particularly if they're final like in enums. I know this is supposed to be ugly but... I don't care as long as it's convenient =)
So...
public class MyApplication extends Application
{
private static MyApplication instance;
private FavouritesManager favouritesManager;
public static getMyApplicationInstance ()
{
return instance;
}
public void onCreate ()
{
instance = this;
favouritesManager = new FavouritesManager(this); // You may want it to have a Context...
}
}
public class FavouritesManager
{
private Map<Integer,Favourites> favorites;
public FavouritesManager ()
{
load();
}
public void add ( Favourite favourite )
{
favourites.put(favourite.id, favourite);
}
public boolean contains ( int favouriteId )
{
favourites.contaisKey(favouriteId);
}
private void load ()
{
favourites = new HashMap<>();
// Maybe deserialize json from SharedPreferenecs?
}
public List<Favorite> getAll ()
{
// Return all Favourites, sorted by their SortOrder.
}
public Favorite create ( String name )
{
// Maybe a factory method that generates an unused id and returns a new Favourite instance?
}
}
public Favourite
{
public final int id;
public final Date createDate;
public String name;
public int sortOrder;
public Favorite ( int id, String name, int sortOrder )
{
this.id = id;
this.createDate = Date();
this.name = name;
this.sortOrder = sortOrder;
}
}
public class MyActivity extend Activity
{
protected void onCreate ( Bundle savedInstanceState )
{
FavouritesManager favmanager = MyApplication.getMyApplicationInstance().getFavoritesManager();
}
{
}
Make your classes Message and SMS implement the same interface IModel. Then, when you implement your methods (e.g. add()) and want them to accept both Message and SMS objects, use the base interface in your method signature:
public class AbstractData {
public static void add(final IModel data) { // <- Use interface here!
// ...
}
}
Now you can add objects this way:
Message msg = new Message();
AbstractData.add(msg);
SMS sms = new SMS();
AbstractData.add(sms);

Using Strings from resources in List.

I'm new to Android and I'm having a problem using String variables from resources in my code. I tried a couple of solutions found on the internet and Android API Guides, but they didn't work in this specific case, could also be me not using them correctly.
To be more specific, I have a Master/Detail flow activity and I would like to use resource strings as item names for multilanguage purposes, but I have a problem with recovering actual strings.
The error I get is:
Cannot resolve method 'getString()'
Here is my code based on android studio dummy file
public class Categories {
public static List<CatName> ITEMS = new ArrayList<CatName>();
static {
String temp = getString(R.string.cat_n1);
addItem(new CatName("1", temp);
}
private static void addItem(CatName item) {
ITEMS.add(item);
}
public static class CatName {
public String id;
public String name;
public FieldCat(String id, String name) {
this.id = id;
this.name = name;
}
#Override
public String toString() {
return name;
}
}}
You need to specify the resource. Try this,
getResources().getString(R.string.cat_n1);
getString(int resId): Return a localized string from the application's package's default string table.
getResources().getString(int id): Returns the string value associated with a particular resource ID. It will be stripped of any styled text information.
Try using it with a constructor passing the context and calling getstring on that
public class Categories {
public static List<CatName> ITEMS = new ArrayList<CatName>();
public Categories(Context ct)
{
String temp = ct.getString(R.string.abc_action_bar_home_description);
addItem(new CatName("1", temp));
}
private static void addItem(CatName item) {
ITEMS.add(item);
}
public static class CatName {
public String id;
public String name;
public CatName(String id, String name) {
this.id = id;
this.name = name;
}
#Override
public String toString() {
return name;
}
}}

putParcelableArrayListExtra and black screen

I have custom class that implements Parcelable and I use it as custom arraylist.
When I use putParcelableArrayListExtra and 400 rows it works fine, but 1000 rows it does not. I have black screen and app locks up. What is wrong?
EDIT:
I sent it here and I don't use it in another Activity.
Intent intent = new Intent().setClass(getApplicationContext(), ArtActivity.class);
intent.putParcelableArrayListExtra ("mylist", list);
startActivityForResult(intent, SECONDARY_ACTIVITY_REQUEST_CODE);
My array:
ArrayList<Piece> list = new ArrayList<Piece>();
It is my Class:
public class Piece implements Parcelable {
private String id;
private String name;
private int type;
private String text;
private String mp3;
public Piece (String id,String name,int type)
{
this.id=id;
this.name=name;
this.type=type;
}
public Piece(Piece ele)
{
this.id=ele.id;
this.name=ele.name;
this.type=ele.type;
this.text=ele.text;
}
public Piece (Parcel in)
{
id = in.readString ();
name = in.readString ();
type = in.readInt();
text= in.readString();
mp3=in.readString();
}
public static final Parcelable.Creator<Piece> CREATOR
= new Parcelable.Creator<Piece>()
{
public Piece createFromParcel(Parcel in)
{
return new Piece(in);
}
public Piece[] newArray (int size)
{
return new Piece[size];
}
};
public void makeText(String text)
{
this.text=text;
}
public void makeMp3(String mp3)
{
this.mp3= mp3;
}
public String getMp3()
{
return this.mp3;
}
public String getId()
{
return id;
}
public String getName()
{
return name;
}
public int getType()
{
return type;
}
public String getText()
{
return text;
}
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
// TODO Auto-generated method stub
dest.writeString (id);
dest.writeString (name);
dest.writeInt(type);
dest.writeString (text);
dest.writeString (mp3);
}
}
I do not believe you should be using parcelable in this case. I would either access the data statically (if you only intend to have one persistent instance of the data), or use a caching system to hold onto the data.
This is an example of a publicly available static variable:
public static List<Piece> list;
It is accessible from everywhere in your app that has visibility of the class.
However, doing this is very messy and is considered a bad practice. Alternatively, you can create an object to manage the data for you as a static class or singleton:
public class MyListManager {
private static List<Piece> mList;
public static List<Piece> getMyList() {
return mList;
}
public static void setList(List<Piece> list) {
mList = list;
}
}
Alternatively, you can implement some kind of a caching system to manage your data.

create a class to model a list

I have a class named Person.This class represents (as the name says) a Person. Now I have to create a class PhoneBook to represent a list of Persons. How can I do this? I don't understand what means "create a class to represent a list".
import java.util.*;
public class Person {
private String surname;
private String name;
private String title;
private String mail_addr;
private String company;
private String position;
private int homephone;
private int officephone;
private int cellphone;
private Collection<OtherPhoneBook> otherphonebooklist;
public Person(String surname,String name,String title,String mail_addr,String company,String position){
this.surname=surname;
this.name=name;
this.title=title;
this.mail_addr=mail_addr;
this.company=company;
this.position=position;
otherphonebooklist=new ArrayList<OtherPhoneBook>();
}
public String getSurname(){
return surname;
}
public String getName(){
return name;
}
public String getTitle(){
return title;
}
public String getMailAddr(){
return company;
}
public String getCompany(){
return position;
}
public void setHomePhone(int hp){
homephone=hp;
}
public void setOfficePhone(int op){
officephone=op;
}
public void setCellPhone(int cp){
cellphone=cp;
}
public int getHomePhone(){
return homephone;
}
public int getOfficePhone(){
return officephone;
}
public int getCellPhone(){
return cellphone;
}
public Collection<OtherPhoneBook> getOtherPhoneBook(){
return otherphonebooklist;
}
public String toString(){
String temp="";
temp+="\nSurname: "+surname;
temp+="\nName: "+name;
temp+="\nTitle: "+title;
temp+="\nMail Address: "+mail_addr;
temp+="\nCompany: "+company;
temp+="\nPosition: "+position;
return temp;
}
}
Your PhoneBook class will likely have a member like this:
private List<Person> book = new ArrayList<Person>();
And methods for adding and retrieving Person objects to/from this list:
public void add(final Person person) {
this.book.add(person);
}
public Person get(final Person person) {
int ind = this.book.indexOf(person);
return (ind != -1) ? this.book.get(ind) : null;
}
Note that a List isn't the best possible representation for a phone book, because (in the worst case) you'll need to traverse the entire list to look up a number.
There are many improvements/enhancements you could make. This should get you started.
Based on the class being named PhoneBook, I assume that you ultimately want to create a mapping between a phone number, and a person. If this is what you need to do then your PhoneBook class should contain a Map instead of a List (but this may depend on other parameters of the project).
public class PhoneBook
{
private Map<String,Person> people = new HashMap<String,Person>();
public void addPerson(String phoneNumber, Person person)
{
people.put(phoneNumber,person);
}
public void getPerson(String phoneNumber)
{
return people.get(phoneNumber);
}
}
In the above, the phone number is represented as a String, which is probably not ideal since the same phone number could have different String representations (different spacing, or dashes, etc). Ideally the Map key would be a PhoneNumber class that takes this all into account in its hashCode and equals functions.
you can do it by creating a class PhoneBook
public class PhoneBook{
Private List<Person> personList = new ArrayList<Person>;
public void addPerson(Person person){
this.personList.add(person);
}
public List getPersonList(){
return this.personList;
}
public Person getPersonByIndex(int index){
return this.personList.get(index);
}
}

Categories