title: How can I add a Context Menu to a Table Layout?
body: <p>Hello fellow Programmers</p>
  
  <p>I am trying myself on an app to log all expenses I make.
  I am entering my info in a form, add it to a SQLite Database and show it in a new activity in a TableLayout. Everything works fine until there, more or less...</p>
  
  <p>This is the Activity where I show the data of my SQLite Table</p>
  
  <pre><code>package com.ascendise.ascBudget;
  
  import androidx.appcompat.app.AppCompatActivity;
  
  import android.content.res.Configuration;
  import android.database.Cursor;
  import android.database.SQLException;
  import android.icu.text.DecimalFormat;
  import android.os.Bundle;
  import android.view.ContextMenu;
  import android.view.ContextMenu.ContextMenuInfo;
  import android.view.MenuInflater;
  import android.view.MenuItem;
  import android.view.View;
  import android.widget.AdapterView.AdapterContextMenuInfo;
  import android.widget.CheckBox;
  import android.widget.TableLayout;
  import android.widget.TableRow;
  import android.widget.TextView;
  
  public class ShowExpensesActivity extends AppCompatActivity {
      private TableLayout tblExpenses;
      private TextView tvMessage;
      private TableOpenHandler toh = new TableOpenHandler(this);
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          Cursor cursor = toh.getCursor(toh.TABLE_NAME_XPNSES);
          Boolean isLandscape = this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
  
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_show_expenses);
          setTitle(R.string.main_button_expenses);
  
          //region Initialization GUI-Elements
          tblExpenses = findViewById(R.id.tblExpenses);
          tvMessage = findViewById(R.id.tvMessage);
          //endregion
  
          //region fill Table
          while(cursor.moveToNext()) {
              try {
                  TableRow row = new TableRow(this);
                  TextView tvArticle = new TextView(this);
                  TextView tvCategory = new TextView(this);
                  TextView tvDescription = new TextView(this);
                  TextView tvDate = new TextView(this);
                  CheckBox ckbxNecessity = new CheckBox(this);
                  TextView tvPrice = new TextView(this);
  
                  String sArticle = cursor.getString(toh.COLUMN_ARTICLE);
                  String sCategory = cursor.getString(toh.COLUMN_CATEGORY);
                  String sDescription = cursor.getString(toh.COLUMN_DESC);
                  String sDate = cursor.getString(toh.COLUMN_DATE);
                  String sPrice = cursor.getString(toh.COLUMN_PRICE);
  
                  DecimalFormat df = new DecimalFormat(getString(R.string.input_decimalFormat));
                  sPrice = df.format(Double.parseDouble(sPrice)).replace(',', '\'');
  
                  tvArticle.setText(sArticle);
                  tvCategory.setText(sCategory);
                  tvDescription.setText(sDescription);
                  tvDate.setText(sDate);
                  ckbxNecessity.setClickable(false);
                  tvPrice.setText(sPrice);
  
                  if (Integer.parseInt(cursor.getString(toh.COLUMN_NT)) == (toh.XPNSES_NECESSITY)) {
                      ckbxNecessity.setChecked(true);
                  } else {
                      ckbxNecessity.setChecked(false);
                  }
  
                  row.addView(tvArticle);
                  row.addView(tvCategory);
                  row.addView(tvDescription);
                  row.addView(tvDate);
                  row.addView(ckbxNecessity);
                  row.addView(tvPrice);
                  row.setClickable(true);
                  registerForContextMenu(row);
                  tblExpenses.addView(row);
              }catch(SQLException ex) {
                  ex.printStackTrace();
              }catch(Exception ex) {
                  ex.printStackTrace();
              }
          }
          //endregion
  
          //region change TableLayout @ OrientationChange
          if(isLandscape){
              tvMessage.setVisibility(View.INVISIBLE);
              tvMessage.setHeight(0);
              tblExpenses.setColumnCollapsed(2,false);
              tblExpenses.setColumnCollapsed(4, false);
          }else{
              tvMessage.setVisibility(View.VISIBLE);
              tblExpenses.setColumnCollapsed(2,true);
              tblExpenses.setColumnCollapsed(4, true);
          }
          //endregion
      }
  
      //closes TableHandler when Activity/App gets closed
      @Override
      public void onDestroy(){
          super.onDestroy();
          toh.close();
      }
  
      @Override
      public void onCreateContextMenu(ContextMenu menu, View v,
                                      ContextMenuInfo menuInfo){
          super.onCreateContextMenu(menu, v, menuInfo);
          MenuInflater inflater = getMenuInflater();
          inflater.inflate(R.menu.context_menu , menu);
          setIntent(getIntent());
      }
  
      @Override
      public boolean onContextItemSelected(MenuItem item){
          AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
          switch(item.getItemId()){
              case R.id.delete:
                  toh.delete(info.id);
                  break;
              case R.id.edit:
                  break;
              default:
                  break;
          }
          return true;
      }
  }
  </code></pre>
  
  <p>Now I am trying to add a Context Menu to that TableLayout, so I can delete rows, but it is not really working. I am getting a NullPointerException when I try to call info.id. I think it has something to do with how I register a view for the ContextMenu. I tried registering the row, the TableLayout etc. Is it even possible to do it like that or does it only work with ListViews?</p>
  
  <p>Here is the StackTrace:</p>
  
  <pre><code>E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.ascendise.ascBudget, PID: 26615
      java.lang.NullPointerException: Attempt to read from field 'long android.widget.AdapterView$AdapterContextMenuInfo.id' on a null object reference
          at com.ascendise.ascBudget.ShowExpensesActivity.onContextItemSelected(ShowExpensesActivity.java:133)
          at android.app.Activity.onMenuItemSelected(Activity.java:3676)
          at androidx.fragment.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:436)
          at androidx.appcompat.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:196)
          at androidx.appcompat.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:109)
          at com.android.internal.policy.PhoneWindow$PhoneWindowMenuCallback.onMenuItemSelected(PhoneWindow.java:3851)
          at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
          at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:178)
          at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:908)
          at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:898)
          at com.android.internal.view.menu.MenuDialogHelper.onClick(MenuDialogHelper.java:166)
          at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1146)
          at android.widget.AdapterView.performItemClick(AdapterView.java:321)
          at android.widget.AbsListView.performItemClick(AbsListView.java:1206)
          at android.widget.AbsListView$PerformClick.run(AbsListView.java:3197)
          at android.widget.AbsListView$3.run(AbsListView.java:4145)
          at android.os.Handler.handleCallback(Handler.java:809)
          at android.os.Handler.dispatchMessage(Handler.java:102)
          at android.os.Looper.loop(Looper.java:166)
          at android.app.ActivityThread.main(ActivityThread.java:7555)
          at java.lang.reflect.Method.invoke(Native Method)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:469)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:963)
  </code></pre>