I'm just starting out with learning Java, and have run into a problem. When trying to run an Android application, I get a NullPointerException when the method makeResponse is called.
Code extract (full code appended at the end of this post):
private String makeResponse(String input){
//This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why.
String response = "You picked "+input;
if (sw==null){
response+=" and sw is null"; //This doesn't activate
}
if (input==null){
response+=" and input is null"; //This doesn't activate
}
int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger.
response+=", that has id "+String.valueOf(id);
return response;
}
(sw is a field of the parent class, set in another method. sw is an instance of a self-made class - full code at the end)
The exception is thrown at the line beginning "int id ="
My initial searching for NullPointerException told me that it was "thrown when an application attempts to use null in a case where an object is required." - hence the two "if" clauses in my code above, to try to find which object was unexpectedly null. Since neither of these are, I concluded that sw.getIdFromName must be returning a null of type Integer (as in this similar problem: Java: null pointer exception when unboxing Integer?). However, I don't see how this is possible in sw.getIdFromName as shown below (nameLookup is a String array, a field of sw):
public int getIdFromName(String name){
for (int i=0;i<267;i++){
if (nameLookup[i].equals(name)){
return i;
}
}
return -1;
}
(Incidentally, if there is a better way of searching a String array for a search term, I would be grateful if someone could tell me - binarySearch doesn't appear to be defined on String arrays).
Following the advice of the top commenter in the question linked above, I tried replacing "int id" with "Integer id" in makeResponse, but with no effect - the same exception is thrown at the same place.
Any advice would be gratefully appreciated.
Judging from the comments in the stackoverflow question linked above, providing a stack trace would not provide any new information, but I'd be happy to do so if asked.
P.s. this is my first question here, so apologies if I make some breach of etiquette or inane mistake.
Full code listings:
ConversationActivity.java:
package com.example.Conversation;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
public class ConversationActivity extends Activity {
/** Called when the activity is first created. */
StationsWrapper sw;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**Setting the adapter for the AutoComplete*/
final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.ACTextView1);
String[] stationsArray = getResources().getStringArray(R.array.stations);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, stationsArray);
textView.setAdapter(adapter);
/**Code below grabs the data from stations.xml and puts it in a readable object */
this.sw = new StationsWrapper();
/** Code below is to set a click function for the AutoComplete*/
OnItemClickListener ACListener = new OnItemClickListener(){
public void onItemClick(AdapterView<?> parent, View v, int position,
long id) {
TextView reply = (TextView) findViewById(R.id.reply);
reply.setText("working...");
String ChosenStation = (String) parent.getItemAtPosition(position);
reply.setText(makeResponse(ChosenStation));
//Toast.makeText(ConversationActivity.this, "You clicked "+parent.getItemAtPosition(position), Toast.LENGTH_SHORT).show();
textView.setText("");
}
};
textView.setOnItemClickListener(ACListener);
}
private String makeResponse(String input){
//This doesn't work yet. I keep getting null pointer exceptions on the line beginning "int id" line, but can't tell why.
String response = "You picked "+input;
if (sw==null){
response+=" and sw is null"; //This doesn't activate
}
if (input==null){
response+=" and input is null"; //This doesn't activate
}
int id = sw.getIdFromName(input); //If this line (and the following one) are commented out, the method runs with no problem, but neither of the if clauses above trigger.
response+=", that has id "+String.valueOf(id);
return response;
}
}
StationsWrapper.java:
package com.example.Conversation;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class StationsWrapper {
private int[][] stats;
private String[] nameLookup;
public StationsWrapper(){
//Constructor. Grabs data from XML, and whacks it into relevant arrays.
//stats is an integer array, indexed first by station id (1-267), and then by datatype (0 for line, 1 for zone)
final int[][] stats = new int[267][2];
final String[] nameLookup = new String[267];
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bline = false;
boolean bzone= false;
String curStation;
int curID;
String curLine;
String curZone;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("STATION")){
curStation=attributes.getValue(0);
curID=Integer.parseInt(attributes.getValue(1));
}
if (qName.equalsIgnoreCase("LINE")) {
bline = true;
}
if (qName.equalsIgnoreCase("ZONE")) {
bzone = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
if (qName.equalsIgnoreCase("Station")){
nameLookup[curID-1]=curStation;
int intLine=(convLineToInt(curLine));
stats[curID-1][0]=intLine;
int intZone=(convZoneToInt(curZone));
stats[curID-1][1]=intZone;
}
}
public void characters(char ch[], int start, int length) throws SAXException {
if (bline) {
//System.out.println("Line : " + new String(ch, start, length));
curLine=new String(ch, start, length);
bline = false;
}
if (bzone) {
//System.out.println("Zone : " + new String(ch, start, length));
curZone=new String(ch, start, length);
bzone = false;
}
}
};
saxParser.parse("c:\\Users\\Jack Jackson\\Coding\\Java\\stations.xml", handler);
} catch (Exception e) {
e.printStackTrace();
}
this.stats=stats;
this.nameLookup=nameLookup;
}
public static void main(String[] args){
//Nothing to see here, move it along folks.
}
public String[] getNameLookup(){
return nameLookup;
}
public int getIdFromName(String name){
for (int i=0;i<nameLookup.length;i++){
if (nameLookup[i].equals(name)){
return i;
}
}
return -1;
}
public int returnData(int id, int datapoint){
return stats[id][datapoint];
}
public void displayStats(){
for (int i=0;i<267;i++){
for (int j=0;j<2;j++){
System.out.print(stats[i][j]);
System.out.print(" ");
}
System.out.println("");
}
}
}
Without running your code, it seems very likely that one of nameLookup array entries is null, so trying to call nameLookup[i].equals() throws a NullPointerException.
If elements of nameLookup can legitimately be null, one way to handle this is to reverse the order of the comparison in getIdFromName():
if (name.equals(nameLookup[i])) {
In any case, I'd recommend that you make sure that both nameLookup itself and its elements are fully initialized.
Related
I would like to implement the library PocketSphinx in my Android project but I fail with it since nothing happens. It doesn't work and I don't get any errors.
This is how I tried it:
Added pocketsphinx-android-5prealpha-release.aar to /app/libs
Added assets.xml to /app
Aded the following to /app/build.gradle:
ant.importBuild 'assets.xml'
preBuild.dependsOn(list, checksum)
clean.dependsOn(clean_assets)
Added sync (with all sub-files) into /app/assets
Cloned the following repos into my root-directory:
git clone https://github.com/cmusphinx/sphinxbase
git clone https://github.com/cmusphinx/pocketsphinx
git clone https://github.com/cmusphinx/pocketsphinx-android
Executed gradle build
This is how my code looks like:
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import ch.yourclick.kitt.R;
import edu.cmu.pocketsphinx.Assets;
import edu.cmu.pocketsphinx.Hypothesis;
import edu.cmu.pocketsphinx.RecognitionListener;
import edu.cmu.pocketsphinx.SpeechRecognizer;
import edu.cmu.pocketsphinx.SpeechRecognizerSetup;
public class SttService extends Service implements RecognitionListener {
private static final String TAG = "SstService";
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
private static final String FORECAST_SEARCH = "forecast";
private static final String DIGITS_SEARCH = "digits";
private static final String PHONE_SEARCH = "phones";
private static final String MENU_SEARCH = "menu";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "oh mighty computer";
/* Used to handle permission request */
private static final int PERMISSIONS_REQUEST_RECORD_AUDIO = 1;
private SpeechRecognizer recognizer;
private HashMap<String, Integer> captions;
public SttService() {
// Prepare the data for UI
captions = new HashMap<>();
captions.put(KWS_SEARCH, R.string.kws_caption);
captions.put(MENU_SEARCH, R.string.menu_caption);
captions.put(DIGITS_SEARCH, R.string.digits_caption);
captions.put(PHONE_SEARCH, R.string.phone_caption);
captions.put(FORECAST_SEARCH, R.string.forecast_caption);
Log.e(TAG, "SttService: Preparing the recognition");
// Recognizer initialization is a time-consuming and it involves IO,
// so we execute it in async task
new SetupTask(this).execute();
}
private static class SetupTask extends AsyncTask<Void, Void, Exception> {
WeakReference<SttService> activityReference;
SetupTask(SttService activity) {
this.activityReference = new WeakReference<>(activity);
}
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(activityReference.get());
File assetDir = assets.syncAssets();
activityReference.get().setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
Log.e(TAG, "onPostExecute: Failed to init recognizer " + result);
} else {
activityReference.get().switchSearch(KWS_SEARCH);
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (recognizer != null) {
recognizer.cancel();
recognizer.shutdown();
}
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
if (text.equals(KEYPHRASE))
switchSearch(MENU_SEARCH);
else if (text.equals(DIGITS_SEARCH))
switchSearch(DIGITS_SEARCH);
else if (text.equals(PHONE_SEARCH))
switchSearch(PHONE_SEARCH);
else if (text.equals(FORECAST_SEARCH))
switchSearch(FORECAST_SEARCH);
else
Log.e(TAG, "onPartialResult: " + text);
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
if (hypothesis != null) {
String text = hypothesis.getHypstr();
Log.e(TAG, "onResult: " + text);
}
}
#Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(KWS_SEARCH))
switchSearch(KWS_SEARCH);
}
private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
String caption = getResources().getString(captions.get(searchName));
Log.e(TAG, "switchSearch: "+ caption);
}
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = SpeechRecognizerSetup.defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
.setRawLogDir(assetsDir) // To disable logging of raw audio comment out this call (takes a lot of space on the device)
.getRecognizer();
recognizer.addListener(this);
/* In your application you might not need to add all those searches.
They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
// Create grammar-based search for selection between demos
File menuGrammar = new File(assetsDir, "menu.gram");
recognizer.addGrammarSearch(MENU_SEARCH, menuGrammar);
// Create grammar-based search for digit recognition
File digitsGrammar = new File(assetsDir, "digits.gram");
recognizer.addGrammarSearch(DIGITS_SEARCH, digitsGrammar);
// Create language model search
File languageModel = new File(assetsDir, "weather.dmp");
recognizer.addNgramSearch(FORECAST_SEARCH, languageModel);
// Phonetic search
File phoneticModel = new File(assetsDir, "en-phone.dmp");
recognizer.addAllphoneSearch(PHONE_SEARCH, phoneticModel);
}
#Override
public void onError(Exception error) {
Log.e(TAG, "onError: " + error.getMessage());
}
#Override
public void onTimeout() {
switchSearch(KWS_SEARCH);
}
}
My code is almost the same as pocketsphinx-android-demo. The only differences are that I am doing this in a service class, instead of an Activity and I am not asking the user for microphone permission since I do that in the MainActity already. Well, my code has some warnings but no errors.
When I run my app, I get this message (see the full stack trace):
E/SstService: switchSearch: To start demonstration say "oh mighty
computer".
But when I say "oh mighty computer" (or anything else), nothing happens. I don't even get an error. So I have no idea where I am stuck and what I am doing wrong.
If there is someone familiar with that library, any help will be appreciated!
This question already has answers here:
How to return DataSnapshot value as a result of a method?
(6 answers)
Closed 4 years ago.
ArrayList<String> getthis=new ArrayList<String>();
getthis.add("username");
getthis.add("status");
*Trying to achive-
method will take above "username","status" and get their value from FirebaseDatabase as new simmilar array,*
And it do so,it retrives the value as log says.
these are the Logs while checking app.
D/FirebaseHelper: Recived name=a#gmail.com
FinalArray have size 1 and Element is a#gmail.com
D/FirebaseHelper: Recived status=hi there buddy
FinalArray have size 2 and Element is hi there buddy
Ide throw below Log before above Logs
D/FirebaseHelper: At last FinalArray have size 0 and Element is []
Recived Array[]
But at the end ,when main method try to return Main Array-then it can't.
Main problem is-
Ide shows no error.but method is unable to return New Array constructed by child method.Which is OnValueEventListner.
these are the main codes
package com.abhishekwork.forwork;
import android.util.Log;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import androidx.annotation.NonNull;
public class HardWork {
private static String tempString;
public static ArrayList<String> getArrayFromFirebase(DatabaseReference databaseReference, final ArrayList<String> arrayList) {
final int inputArraySize = arrayList.size();
final ArrayList<String> finalArrayList = new ArrayList<>(inputArraySize);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (int i = 0; i < inputArraySize; i++) {
tempString = dataSnapshot.child(arrayList.get(i)).getValue().toString();
Log.d("FirebaseHelper","Recived"+arrayList.get(i) + "=" + tempString);
finalArrayList.add(i,Temp_String);
Log.d("FirebaseHelper","FinalArray has size" + finalArrayList.size() + " and Element is " + finalArrayList.get(i));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Log.d("FirebaseHelper", "At last FinalArray have size" + finalArrayList.size() + "and Element is " + finalArrayList.toString());
Log.d("FirebaseHelper", "Recieved Array" + finalArrayList);
return finalArrayList;
}
}
When you call addValueEventListener() on the DatabaseReference, you are adding a listener that will have it's onDataChange() method fired when the data snapshot is ready (or the onCancelled() will be fired if there was an error).
These events are asynchronous and they probably happen only after you return your from your method and that's why you are getting the empty list.
The simplest way to get the results you need would be using a callback to do work when the results are ready.
Here's a great answer which you can refer to.
I have the following code I am using, trying to set up Espresso:
import android.support.test.espresso.Espresso;
import android.support.test.espresso.contrib.RecyclerViewActions;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.action.ViewActions.click;
#RunWith(AndroidJUnit4.class)
public class EspressoTest {
#Rule
public ActivityTestRule<MainActivity> firstRule = new ActivityTestRule<>(MainActivity.class);
#Test
public void testRecyclerViewClick() {
Espresso.onView(ViewMatchers.withId(R.id.recycler_view_ingredients)).perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));
}
}
It will not run successfully and I do not understand why. Below is the error:
Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(is assignable from class: class android.support.v7.widget.RecyclerView and is displayed on the screen to the user)
Target view: "RecyclerView{id=2131165335, res-name=recycler_view_ingredients, visibility=VISIBLE, width=1440, height=0, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=true, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.constraint.ConstraintLayout$LayoutParams#caad301, tag=null, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=0}"
at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:245)
at android.support.test.espresso.ViewInteraction.access$100(ViewInteraction.java:63)
at android.support.test.espresso.ViewInteraction$1.call(ViewInteraction.java:153)
at android.support.test.espresso.ViewInteraction$1.call(ViewInteraction.java:150)
Full Github Repo:
https://github.com/troy21688/KitchenPal
EDIT: The test actually passed on an emulator, but not my actual phone (Google Nexus 6). It leads me to believe it has something to do with how the screen size is being rendered on each device.
Your RecyclerView with id recycler_view_ingredients has a height of wrap_content, so when it has no children or the adapter is empty, then the height will be 0. The error says that action will not be performed because the target view RecyclerView is not displayed (height=0), which also means that the data has not loaded yet at the time.
Your app is loading data asynchronously on different thread, then update your RecyclerView on the main thread when it has completely loaded. As a matter
of fact, Espresso only synchronizes on main thread, so when your app starts to load data in the background, it thinks that the main thread of the app has gone idle, and so it proceeds to perform the action, which may or may not fail depends on devices performance.
An easy way to fix this issue is to add some delay, say a second:
Thread.sleep(1000);
onView(withId(R.id.recycler_view_ingredients)).perform(actionOnItemAtPosition(0, click()));
Or, an elegant way to fix it is to use IdlingResource:
onView(withId(R.id.recycler_view_ingredients))
.perform(
waitUntil(hasItemCount(greaterThan(0))), // wait until data has loaded
actionOnItemAtPosition(0, click()));
And here are some complimentary classes:
public static Matcher<View> hasItemCount(Matcher<Integer> matcher) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
#Override public void describeTo(Description description) {
description.appendText("has item count: ");
matcher.describeTo(description);
}
#Override protected boolean matchesSafely(RecyclerView view) {
return matcher.matches(view.getAdapter().getItemCount());
}
};
}
public static ViewAction waitUntil(Matcher<View> matcher) {
return actionWithAssertions(new ViewAction() {
#Override public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(View.class);
}
#Override public String getDescription() {
StringDescription description = new StringDescription();
matcher.describeTo(description);
return String.format("wait until: %s", description);
}
#Override public void perform(UiController uiController, View view) {
if (!matcher.matches(view)) {
LayoutChangeCallback callback = new LayoutChangeCallback(matcher);
try {
IdlingRegistry.getInstance().register(callback);
view.addOnLayoutChangeListener(callback);
uiController.loopMainThreadUntilIdle();
} finally {
view.removeOnLayoutChangeListener(callback);
IdlingRegistry.getInstance().unregister(callback);
}
}
}
});
}
private static class LayoutChangeCallback implements IdlingResource, View.OnLayoutChangeListener {
private Matcher<View> matcher;
private IdlingResource.ResourceCallback callback;
private boolean matched = false;
LayoutChangeCallback(Matcher<View> matcher) {
this.matcher = matcher;
}
#Override public String getName() {
return "Layout change callback";
}
#Override public boolean isIdleNow() {
return matched;
}
#Override public void registerIdleTransitionCallback(ResourceCallback callback) {
this.callback = callback;
}
#Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
matched = matcher.matches(v);
callback.onTransitionToIdle();
}
}
When your test works in one device and fails in another %90 of the time, it is because of synchronization issues (your test tries to do an assertion/action before network call completes) and %9 of the time it is because you need to scroll the view in some devices because screen sizes are different. While Aaron's solution may work it is very hard to use IdlingResources for big projects and idling resource make your tests wait 5 seconds each time it waits. Here is a simpler approach that waits for your matcher to succeed in every possible case
fun waitUntilCondition(matcher: Matcher<View>, timeout: Long = DEFAULT_WAIT_TIMEOUT, condition: (View?) -> Boolean) {
var success = false
lateinit var exception: NoMatchingViewException
val loopCount = timeout / DEFAULT_SLEEP_INTERVAL
(0..loopCount).forEach {
onView(matcher).check { view, noViewFoundException ->
if (condition(view)) {
success = true
return#check
} else {
Thread.sleep(DEFAULT_SLEEP_INTERVAL)
exception = noViewFoundException
}
}
if (success) {
return
}
}
throw exception
}
You can use it like
waitUntilCondition`(withId(id), timeout = 20000L) { it!= null}`
I have a program that is an extremely basic login:
import javax.swing.JOptionPane.*;
import java.lang.Math.*;
import java.lang.System.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.JFrame;
public class UserLog extends JFrame
{
public static void main(String[]Args) throws InterruptedException
{
boolean isValid=false;
while(!isValid)
{
// Components related to "login" field
JLabel label_loginname = new JLabel("Enter your login name:");
JTextField loginname = new JTextField(15);
// loginname.setText("EnterLoginNameHere");
// Pre-set some text
// Components related to "password" field
JLabel label_password = new JLabel("Enter your password:");
JPasswordField password = new JPasswordField();
// password.setEchoChar('#');
// Sets # as masking character
// password.setEchoChar('\000');
// Turns off masking
JCheckBox rememberCB = new JCheckBox("Remember me");
Object[] array = {label_loginname,
loginname,
label_password,
password,
rememberCB};
Object[] options = {"Login", "Cancel"};
int res = JOptionPane.showOptionDialog(null,
array,
"Login",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options, //the titles of buttons
options[0]); //default button title
// User hit Login
if (res == 0)
{
System.out.println( "Login" );
}
// User hit CANCEL
if (res == 1)
{
System.out.println( "Canceled" );
}
// User closed the window without hitting any button
if (res == JOptionPane.CLOSED_OPTION)
{
System.out.println( "CLOSED_OPTION" );
}
// Output data in "login" field, if any
String newloginname = loginname.getText();
String newpassword = new String(password.getPassword());
if (newloginname.equalsIgnoreCase("Cody_Coulter") && newpassword.equals("cheche1"))
{
System.out.println("Login Successful!");
boolean selectedCB = rememberCB.isSelected();
System.out.println( "selectedCB: " + selectedCB );
Thread.sleep(3000);
Object[] array1= {"It's about time to choose"};
Object[] options1= {"Leave", "Keep Going"};
int res1 = JOptionPane.showOptionDialog(null,
array1,
"There",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options1, //the titles of buttons
options1[0]); //default button title
if(res1==1)
{
Object[] options2 = {"Answers for Algebra",
"Answers for APUSH",
"Answers for Computer Science"};
Object[] array2={"Pick Your Poison:"};
int res2= JOptionPane.showOptionDialog(null,
array2,
"This",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
null, //do not use a custom Icon
options2, //the titles of buttons
options2[0]); //default button title
if (res2 == 0)
{
JOptionPane.showMessageDialog(null, "Nigguh you a cheatuh" );
}
else
if (res2 == 1)
{
JOptionPane.showMessageDialog(null, "Nigguh, who's dumb enough to need to cheat in APUSH" );
}
else
if (res2 == 2)
{
JOptionPane.showMessageDialog(null, "Nigguh, you dumb" );
}
String name1 = JOptionPane.showInputDialog(null,
"What is your name?");
int length = 0;
length = newpassword.length();
String Pass = "*";
newpassword =newpassword.replaceAll(".","*");
System.out.println("Username: "+newloginname+"\nPassword: "+
newpassword+"\nName: "+name1);
}
}
else {
JOptionPane.showMessageDialog(null,"Wrong Username or Password!");
isValid=false;
}
}
// Output data in "password" field, if any
// Output state of "remember me" check box
}
}
What I want to do is create another program, such as a fileshare, file access, or even a basic game but be able to have this login implemented in order to, of course, login. Is there a way to implement this code without having to copy and paste into another code as a separate class within that file?
Example:
public class NewGame{
public static void main(String[] args)
{
new UserLog();
}
of course this may not be syntactually correct, but that's the gist of it.
Thank you, and if I need to rephrase it or edit the question/format, let me know! :)
EDIT
After making the current main method a regular public class, and call from the newly public class, by the new main
public class gameLogin
{
public static void main(String[]args)
{
userLogin();
}
public class userLogin()
{
// current code, evidently seen in the current main
}
// rest of code
So in order to reference to the original file, userLog, I would have to (in the new file: gameLogin) use
userLog();
or would it be better to use
userLog.userLogin("Munkeeface", "password");
The simplest method would be to simply move all code from your main into a static utility-class function, and then call that function from your other classes mains. For example:
public class LoginToWebsiteUtil {
public static final void login(String username, String password, ...) {
//CODE GOES HERE
}
}
And use it with:
public class LoginToMyWebsite {
public static final void main(String[] ignored) {
LoginToWebsiteUtil.login("myname", "password", ...)
}
}
The only tricky thing will be answering the question: "what variables save state?" Those variables must be declared as static class fields in the utility class. This is because, as soon as the function ends, all state, such as the login-connection, will be terminated. In order to keep it around ("hold its state"), these state variables need to have a larger scope than just the lifetime of the function.
For example, instead of
public class LoginToWebsiteUtil {
public static final void login(String username, String password, ...) {
Connection conn = getConnectionFromLogin(username, password);
//and so on...
It will have to be
public class LoginToWebsiteUtil {
private static Connection conn = null;
public static final void login(String username, String password, ...) {
conn = getConnectionFromLogin(username, password);
//and so on...
Alternatively, you could put all the code from your original main function into the constructor of a new class, such as
public class UserLogin {
private static Connection conn = null;
public UserLog(String username, String password, ...) {
conn = getConnectionFromLogin(username, password);
//CODE HERE
}
}
But, as you can see, you still have the "what holds state?" issue.
(This is a good problem. It sounds like this login code is potentially useful in the future for you.)
Use a public method in the login class that returns whether the user has logged in or not. In the class that calls it use userLog log=new userLog(), then repeatedly call the method. If it returns true, then the user has successfully logged in.
From your code the first step (although not the best one) could be:
public class NewGame{
public static void main(String[] args) {
UserLog.main();
}
Better if you change the signature of your UserLog.main() method to have a non-static method of UserLog, e.g.
public class UserLog extends JFrame {
public void newMethod(String[] args) throws InterruptedException {
// your code in old main method
}
}
and use this method from another class as follows:
public class NewGame {
public static void main(String[] args) {
UserLog userLog = new UserLog;
userLog.newMethod(args);
}
}
If you don't pass any arguments to newMethod you can remove the params String[] args in the method definition and in the call userLog.newMethod()
Here are following my classes:
StatsObjectId.java
public class StatsObjectId extends Activity {
DBClass db;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
db = new DBClass(this);
}
public void addObjId(String objid){
Log.e("objectid","This is the object id going to store: "+objid);
db.addObjectId(objid); //This is the line# 105
if(getObjId()){
Log.e("objectid","Successfully stored!");
}else{
Log.e("objectid","Error in storing object id!");
}
}
public boolean getObjId(){
boolean result;
try{
c = db.getObjectId();
c.moveToFirst();
String str = c.getString(c.getColumnIndex("objectid"));
Log.e("objectid","Object id returned form DB: "+str);
result = true;
}catch(CursorIndexOutOfBoundsException e){
Log.e("objectid","Cursor index out of bound");
result = false;
e.printStackTrace();
}catch(Exception e){
Log.e("objectid","Some Another Exception");
result = false;
e.printStackTrace();
}
return result;
}
ParseComServerAccessor.java
public class ParseComServerAccessor {
//I am skipping some irrelevant code
public void putStats(String authtoken, String userId, Tas statsToAdd) throws Exception {
//Again skip some code
//Here I got some HttpResponse and I need to extract an object id and save it to database
HttpResponse response = httpClient.execute(httpPost);
String responseString = EntityUtils.toString(response.getEntity());
JSONObject json = new JSONObject(responseString);
Log.e("objectid","Now Object Id is: "+json.getString("objectId") );
StatsObjectId ob = new StatsObjectId();
ob.addObjId(json.getString("objectId")); // This is the line#156
//skip some code
}
}
TasSyncAdapter.java
public class TasSyncAdapter extends AbstractThreadedSyncAdapter {
//skipped Constructor code
public void onPerformSync(Account account, Bundle extras, String authority,
ContentProviderClient provider, SyncResult syncResult) {
//skipped some code
ParseComServerAccessor parseComService = new ParseComServerAccessor();
//skipped some code again
parseComService.putStats(authToken, userObjectId, remoteTas); //This is the line# 134
//skip some code
}
}
Now finally when I run my app... this is the following Log Cat
Tag Text
objectid This is the object id going to store: 9AFysqffz7
System.err java.lang.NullPointerException
System.err at com.myapp.ds_app.StatsObjectId.addObjId(StatsObjectId.java:105)
System.err at com.myapp.ds_app.syncadapter.ParseComServerAccessor.putStats(ParseComServerAccessor.java:156)
System.err at com.myapp.ds_app.syncadapter.TasSyncAdapter.onPerformSync(TasSyncAdapter.java:134)
System.err at android.content.AbstractThreadedSyncAdapter$SyncThread.run(AbstractThreadedSyncAdapter.java:254)
DBClass.java
public class DBClass extends SQLiteOpenHelper {
private static final String DATABASE_NAME="myapp.db";
public DBClass(Context cxt){
super(cxt, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase mydatabase) {
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS temp (objectid STRING)");
}
public Cursor getObjectId(){
Cursor cursor = getReadableDatabase().rawQuery("SELECT objectid FROM temp", null);
return cursor;
}
public void addObjectId(String objid){
try{
ContentValues cv = new ContentValues(1);
Log.e("objectid","In DBClass and object id: "+objid);
cv.put("objectid", objid);
Log.e("objectid","Content value contains: "+cv.toString());
getWritableDatabase().insert("temp", "objectid", cv);
}catch(NullPointerException e){
e.printStackTrace();
}
}
}
Now, I am stucked at this point!
So far, I need to save just a single value. I tried to create a file instead of saving a value in database. But again there is some exception of ContextWrapper.
I am currently interested to deal with database.
Please let me know if you guys need any other information.
I would really appreciate if any one please explain this thing. I'm android newbie and would love to learn about this problem. Thanks in advance!
StatsObjectId ob = new StatsObjectId();
You are instanciating an Activity class. You are not allowed to do that. (There should really be something in Android to tell you when you do that) Basically, the context is not initialized, because android needs to do that in order to have a functional Activity.
Plus, Android (when it creates the Activity) calls the onCreate method with a proper context. You don't (and you can't, either), therefore your db is null.
In AbstractThreadedSyncAdapter, you have a getContext method to get a proper context. Use this to initialize your database and to insert data in it, rather than passing it to the Activity object.