0

So this is actually an update to my previous (now deleted) subpar post about the custom adapter-for some reason it thinks I'm generating null object references for it and won't work as a result.

These are the components of my project:

DBHelper-supplementary section:

package com.myapplicationdev.android.songdbmanager;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

import androidx.annotation.Nullable;

import java.util.ArrayList;


public class DBHelper extends SQLiteOpenHelper {    // Start version with 1
    // increment by 1 whenever db schema changes.
    private static final int DATABASE_VER = 1;
    private static final String TABLE_SONG = "song";
    private static final String COLUMN_ID = "id";
    private static final String COLUMN_TITLE = "title";
    private static final String COLUMN_SINGERS = "singers";
    private static final String COLUMN_YEAR="year";
    private static final String COLUMN_STARS="stars";
    // Filename of the database
    private static final String DATABASE_NAME = "songs.db";

    public DBHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VER);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String dropTableSql = "DROP TABLE IF EXISTS " + TABLE_SONG;
        db.execSQL(dropTableSql);
        String createTableSql = "CREATE TABLE " + TABLE_SONG +  "("
                + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
                + COLUMN_TITLE + " TEXT,"
                + COLUMN_SINGERS+ " TEXT ,"
                + COLUMN_YEAR + " INTEGER ,"
                + COLUMN_STARS+ " INTEGER )";
        db.execSQL(createTableSql);
        Log.i("info" ,"created tables");


    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_SONG);
        // Create table(s) again
        onCreate(db);


    }
    public void insertSong(String title, String singers, int year, int stars){

        // Get an instance of the database for writing
        SQLiteDatabase db = this.getWritableDatabase();
        // We use ContentValues object to store the values for
        //  the db operation
        ContentValues values = new ContentValues();
        // Store the column name as key and the description as value
        values.put(COLUMN_TITLE, title);
        values.put(COLUMN_SINGERS, singers);
        values.put(COLUMN_YEAR, year);
        values.put(COLUMN_STARS, stars);

        // Store the column name as key and the date as value

        // Insert the row into the TABLE_TASK
       db.insert(TABLE_SONG, null, values);
        // Close the database connection
        db.close();
    }
    public ArrayList<song> getAllSongs() {
        ArrayList<song> songlist = new ArrayList<>();

        SQLiteDatabase db = this.getReadableDatabase();

        String[] columns= {COLUMN_ID, COLUMN_TITLE, COLUMN_SINGERS,COLUMN_YEAR,COLUMN_STARS};

        Cursor cursor = db.query(TABLE_SONG, columns, null, null,
                null, null, null, null);

        if (cursor.moveToFirst()) {
            do {
                int id = cursor.getInt(0);
                String title=cursor.getString(1);
                String singers = cursor.getString(2);
                int year=cursor.getInt(3);
                int stars=cursor.getInt(4);
                song Song = new song(id,title,singers,year,stars);
                songlist.add(Song);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return songlist;
    }
    public ArrayList<song> getBestSongs() {
        ArrayList<song> bestsonglist = new ArrayList<>();

        SQLiteDatabase db = this.getReadableDatabase();

        String[] columns= {COLUMN_ID, COLUMN_TITLE, COLUMN_SINGERS,COLUMN_YEAR,COLUMN_STARS};
        String condition = COLUMN_STARS + "= ?";
        String[] args = {"5"};
        Cursor cursor = db.query(TABLE_SONG, columns, condition, args,
                null, null, null, null);

        if (cursor.moveToFirst()) {
            do {
                int id = cursor.getInt(0);
                String title=cursor.getString(1);
                String singers = cursor.getString(2);
                int year=cursor.getInt(3);
                int stars=cursor.getInt(4);
                song Song = new song(id,title,singers,year,stars);
                bestsonglist.add(Song);
            } while (cursor.moveToNext());
        }
        cursor.close();
        db.close();
        return bestsonglist;
    }
    public int updateSong(song Song) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(COLUMN_TITLE, Song.getTitle());
        values.put(COLUMN_SINGERS, Song.getSingers());
        values.put(COLUMN_YEAR, Song.getYear());
        values.put(COLUMN_STARS, Song.getStars());
        String whereClause = COLUMN_ID + "=?";
        String[] whereArgs = {String.valueOf(Song.getId())};
        int result=db.update(TABLE_SONG, values, whereClause, whereArgs);

        if (result < 1) {
            Log.d("DBHelper", "Update failed");

            db.close();
            return result;
        }


        return result;
    }
    public void deleteSong(int songId) {
        SQLiteDatabase db = this.getWritableDatabase();
        String whereClause = COLUMN_ID + "=?";
        String[] whereArgs = {String.valueOf(songId)};
       db.delete(TABLE_SONG, whereClause, whereArgs);
       db.close();
    }}

MainActivity-where the initial processing is done:

package com.myapplicationdev.android.songdbmanager;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.ToggleButton;

import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {

    Button btnInsert, btnGetSongs;
    TextView tvResults;

    EditText YearInput;
    EditText SongInput;
    EditText SingerInput;
    RadioGroup RadioGroupRating;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnInsert = findViewById(R.id.btnInsert);
        btnGetSongs = findViewById(R.id.btnGetTasks);
        //List View->
        YearInput=findViewById(R.id.insertYear);
        SongInput=findViewById(R.id.insertTitle);
        SingerInput=findViewById(R.id.insertSingers);
        RadioGroupRating=findViewById(R.id.radio_group);


        btnInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DBHelper db = new DBHelper(MainActivity.this);
                String title=SongInput.getText().toString();
                String singers=SingerInput.getText().toString();
                int year=Integer.parseInt(YearInput.getText().toString());

                int selectedRatingId=RadioGroupRating.getCheckedRadioButtonId();
                RadioButton selectedRatingButton=findViewById(selectedRatingId);
                int rating=Integer.parseInt(selectedRatingButton.getText().toString());
                db.insertSong(title,singers,year,rating);

                SongInput.setText("");
                SingerInput.setText("");
                YearInput.setText("");
                RadioGroupRating.clearCheck();
            }
        });

        btnGetSongs.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                // Create the DBHelper object, passing in the
                // activity's Context

                // Insert a task
                Intent intent = new Intent(MainActivity.this, EditActivity.class);
                //Label the actual editactivity EditActivity2
                startActivity(intent);


            }
        });
    }



}

EditActivity:Where the list is displayed:

{
    ListView lv;
    ArrayList<song> songsList;
    //ArrayAdapter<song> adapter;
    CustomAdapter adapter;
    Button fivestarsongs;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit);

        lv = findViewById(R.id.list_view);
        fivestarsongs = findViewById(R.id.btnShow5starsongs);
        DBHelper db = new DBHelper(EditActivity.this);
        songsList = db.getAllSongs();

        //ArrayAdapter<song> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, songs);

        if (songsList != null && !songsList.isEmpty()) {
            adapter = new CustomAdapter(this, android.R.layout.simple_list_item_1, songsList); // Remove the CustomAdapter declaration here
            lv.setAdapter(adapter);
        }

        fivestarsongs.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ArrayList<song> BestSongs = db.getBestSongs();
                adapter.clear();
                adapter.addAll(BestSongs);
                adapter.notifyDataSetChanged();
            }
        });
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int
                    position, long id) {
                song ClickedSong = songsList.get(position);
                Intent i = new Intent(EditActivity.this,
                        MainActivity2.class);
                i.putExtra("song", ClickedSong);
                startActivity(i);
            }
        });
    }

}

MainActivity2-supposed to handle delete/update:

package com.myapplicationdev.android.songdbmanager;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
import android.widget.RadioGroup;


public class MainActivity2 extends AppCompatActivity {

    Button btnUpdate,btnCancel,btnDelete;
    EditText YearInput;
    EditText SongInput;
    EditText SingerInput;
    RadioGroup RadioGroupRating;

    song selectedSong;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        DBHelper db = new DBHelper(MainActivity2.this);
        Intent intent = getIntent();
        song clickedSong = (song) intent.getSerializableExtra("song");

        btnUpdate=findViewById(R.id.btnupdate);
        btnCancel=findViewById(R.id.btnCancel);
        btnDelete=findViewById(R.id.btndelete);
        YearInput=findViewById(R.id.insertYear);
        SongInput=findViewById(R.id.insertTitle);
        SingerInput=findViewById(R.id.insertSingers);

        RadioGroupRating=findViewById(R.id.radio_group);

        selectedSong = clickedSong;
        YearInput.setText(String.valueOf(clickedSong.getYear()));
        SongInput.setText(clickedSong.getTitle());
        SingerInput.setText(clickedSong.getSingers());
        setStarsSelection(selectedSong.getStars());


        btnUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                selectedSong.setTitle(SongInput.getText().toString());
                selectedSong.setSingers(SingerInput.getText().toString());
                selectedSong.setYear(Integer.parseInt(YearInput.getText().toString()));
                selectedSong.setStars(getSelectedStars());
                db.updateSong(selectedSong);
                db.close();
                finish();
            }
        });
        btnDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                db.deleteSong(selectedSong.getId());
                db.close();
                finish();
            }
        });
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MainActivity2.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        });


}

    private int getSelectedStars() {
        int selectedId = RadioGroupRating.getCheckedRadioButtonId();
        RadioButton rbSelected = findViewById(selectedId);
        return Integer.parseInt(rbSelected.getText().toString());
    }
    private void setStarsSelection(int stars) {
        int radioButtonId = 0;
        switch (stars) {
            case 1:
                radioButtonId = R.id.radio_1;
                break;
            case 2:
                radioButtonId = R.id.radio_2;
                break;
            case 3:
                radioButtonId = R.id.radio_3;
                break;
            case 4:
                radioButtonId = R.id.radio_4;
                break;
            case 5:
                radioButtonId = R.id.radio_5;
                break;
        }
        RadioGroupRating.check(radioButtonId);
    }


    }

Song-class involved in all this:

package com.myapplicationdev.android.songdbmanager;

import androidx.annotation.NonNull;

import java.io.Serializable;

public class song implements Serializable {
    private int id;
    private String title;
    private String singers;
    private int year;
    private int stars;


    public void setSingers(String singers) {
        this.singers = singers;
    }

    public void setStars(int stars) {
        this.stars = stars;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public song (
                 String title,
                 String singers,
                 int year,
                 int stars
    ){
        this.title=title;
        this.singers=singers;
        this.year=year;
        this.stars=stars;
    }
    public song (
            int id,
            String title,
            String singers,
            int year,
            int stars
    ){
        this.id=id;
        this.title=title;
        this.singers=singers;
        this.year=year;
        this.stars=stars;
    }
    public String getTitle() {
        return title;
    }
    public int getId(){
        return id;
    }

    public int getYear() {
        return year;
    }

    public int getStars() {
        return stars;
    }

    public String getSingers() {
        return singers;
    }


    @NonNull
    @Override
    public String toString() {
        return
                "title='" + title + '\'' +
                ", singers='" + singers + '\'' +
                ", year=" + year +
                ", stars=" + stars
               ;
    }
}

CustomAdapter:

public class CustomAdapter extends ArrayAdapter {
    private Context context;
    private int layoutResourceId;
    private ArrayList<song> songList;

    public CustomAdapter(Context context, int resource, ArrayList<song> objects) {
        super(context, resource, objects);
        this.context = context;
        this.layoutResourceId = resource;
        this.songList = objects;
    }

    @NonNull
    @Override
    public View getView(int position, View rowView, ViewGroup parent) {
        if (rowView == null) {
            LayoutInflater inflater = LayoutInflater.from(context);
            rowView = inflater.inflate(layoutResourceId, parent, false);
        }

        song currentSong = songList.get(position);

        TextView yearInput = rowView.findViewById(R.id.insertYear);
        TextView singerInput = rowView.findViewById(R.id.insertSingers);
        TextView titleInput = rowView.findViewById(R.id.insertTitle);
        RadioGroup radioGroupRating =rowView.findViewById(R.id.radio_group);

        titleInput.setText(currentSong.getTitle());
        singerInput.setText(currentSong.getSingers());
        yearInput.setText(String.valueOf(currentSong.getYear()));

        int selectedValue = currentSong.getStars();
        int radioButtonId = 0;
        switch (selectedValue) {
            case 1:
                radioButtonId = R.id.radio_1;
                break;
            case 2:
                radioButtonId = R.id.radio_2;
                break;
            case 3:
                radioButtonId = R.id.radio_3;
                break;
            case 4:
                radioButtonId = R.id.radio_4;
                break;
            case 5:
                radioButtonId = R.id.radio_5;
                break;
        }
        radioGroupRating.check(radioButtonId);

        return rowView;


}}

And here's the error message associated with these (I'd share the full stack but the text limit likely won't allow me):

It refers to the line where I set the year in the adapter, which is otherwise working as intended.

FATAL EXCEPTION: main
                                                                                                    Process: com.myapplicationdev.android.songdbmanager, PID: 27730
                                                                                                    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
                                                                                                        at com.myapplicationdev.android.songdbmanager.CustomAdapter.getView(CustomAdapter.java:44)
                                                                                                        at android.widget.AbsListView.obtainView(AbsListView.java:2387)
                                                                                                        at android.widget.ListView.makeAndAddView(ListView.java:2067)
                                                                                                        at android.widget.ListView.fillDown(ListView.java:793)
                                                                                                        at android.widget.ListView.fillFromTop(ListView.java:855)
                                                                                                        at android.widget.ListView.layoutChildren(ListView.java:1838)
                                                                                                        at android.widget.AbsListView.onLayout(AbsListView.java:2184)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
                                                                                                        at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1818)
                                                                                                        at android.widget.LinearLayout.onLayout(LinearLayout.java:1584)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
                                                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
                                                                                                        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
                                                                                                        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
                                                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
                                                                                                        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
                                                                                                        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
                                                                                                        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
                                                                                                        at com.android.internal.policy.DecorView.onLayout(DecorView.java:784)
                                                                                                        at android.view.View.layout(View.java:22844)
                                                                                                        at android.view.ViewGroup.layout(ViewGroup.java:6389)
                                                                                                        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3470)
                                                                                                        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2938)
                                                                                                        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
                                                                                                        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
                                                                                                        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
                                                                                                        at android.view.Choreographer.doCallbacks(Choreographer.java:796)
                                                                                                        at android.view.Choreographer.doFrame(Choreographer.java:731)
                                                                                                        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:938)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at android.os.Looper.loop(Looper.java:223)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7656)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

I tried editing the code to check for nulls and even making an object just to check if that's causing the glitch.

Neither of them had much of an effect.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197

0 Answers0