Data not transferring between classes - android-studio

I have three linked lists called "Titles" (String linked list), "Descriptions" (String linked list), and "Pictures" (Bitmap linked list). I'm 100% sure that they are full of data. I've printed out their data just before the line MyAdapter myAdapter = new MyAdapter(this, Titles, Descriptions, Pictures); and it has exactly the data I expect ("MyAdapter" is a class). However, in the MyAdapter class, all three linked lists are null, as I get the following error:
2022-08-07 19:13:03.009 14983-14983/com.example.usshop E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.usshop, PID: 14983
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.util.LinkedList.add(java.lang.Object)' on a null object reference
at com.example.usshop.MyAdapter.<init>(MyAdapter.java:30)
at com.example.usshop.Shop.CreateItems(Shop.java:70)
at com.example.usshop.Shop$1.onDataChange(Shop.java:56)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
Below is the code of the two classes (Note: for the "Shop" class, the "CreateItems" method mainly matters because it sends the data to the other class. Included the rest in case it somehow affects the issue):
public class Shop extends AppCompatActivity {
RecyclerView rv;
//Below is unimportant; ignore.
/*
String s1[], s2[];
int images[] = {R.drawable.apple, R.drawable.banana, R.drawable.graoe,
R.drawable.orange, R.drawable.pineapple, R.drawable.peach};
*/
LinkedList<String> Titles = new LinkedList<>(), Descriptions = new LinkedList<>();
LinkedList<Integer> Prices = new LinkedList<>();
LinkedList<Bitmap> Pictures = new LinkedList<>();
DatabaseReference ItemsReference = FirebaseDatabase.getInstance().getReference("Items");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shop);
//Whenever the value of ItemsReference changes, it is stored
ItemsReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
// Storing all of the data
for (DataSnapshot DS : snapshot.getChildren()) {
BackendDataStorage TempData = DS.getValue(BackendDataStorage.class);
Titles.add(TempData.getTitle());
Descriptions.add(TempData.getDescription());
Prices.add(TempData.getPrice());
Pictures.add(Extras.StringToBitMap(TempData.getPicture()));
}
CreateItems();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
Log.d("Error", "Failed to read value: " + error.getMessage());
}
});
}
public void CreateItems () {
Log.d("index", Titles.get(0)); // Just making sure Titles isn't null
rv = findViewById(R.id.Recycler_View);
MyAdapter myAdapter = new MyAdapter(this, Titles, Descriptions, Pictures);
rv.setAdapter(myAdapter);
rv.setLayoutManager(new LinearLayoutManager(this));
}
}
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private LinkedList<String> data1, data2;
private LinkedList<Bitmap> images;
private Context context;
public MyAdapter (Context ct, LinkedList<String> s1, LinkedList<String> s2, LinkedList<Bitmap> img) {
context = ct;
// Looping through LinkedList indexes & replacing with new variables
for (int i = 0; i < s1.size(); i++) {
data1.add(s1.get(i));
data2.add(s2.get(i));
images.add(img.get(i));
}
}
}

However, in the MyAdapter class, all three linked lists are null
No, they are not. You have misread the error message. The error is not about any of the arguments you pass to the MyAdapter constructor, but about a member of the MyAdapter class.
Note for instance that there is no error on evaluating s1.size() in the for loop heading, so s1 is not null.
But the error is not about s1, s2 or img. It is about calling the add method on a null reference:
java.lang.NullPointerException: Attempt to invoke virtual method boolean java.util.LinkedList.add(java.lang.Object) on a null object reference
The line where add is called, is here:
data1.add(s1.get(i));
So, data1 is null. And this is indeed the case. Your class has a private instance member called data1 which has not been initialised. You need to do something like:
data1 = new LinkedList<String>();

Related

"java.lang.IllegalArgumentException: view must not be null" Program Closes when navigated

The app closes whenever I navigate to ProfileActivity.
FATAL EXCEPTION: main Process: hfad.com.hallofmemesprototype, PID:
19092 java.lang.RuntimeException: Unable to start activity
ComponentInfo{hfad.com.hallofmemesprototype/hfad.com.hallofmemesprototype.Profile.ProfileActivity}:
java.lang.IllegalArgumentException: view must not be null
Here's the "ProfileActivity" code.
public class ProfileActivity extends AppCompatActivity {
private static final int ACTIVITY_NUM = 3;
private Context mContext = ProfileActivity.this;
private ProgressBar mProgressBar;
private ImageView profilePhoto;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
setupBottomNavigationView();
setupToolbar();
setupActivityWidgets();
setProfileImage();
}
private void setProfileImage(){
String imgURL = "www.androidzone.org/wp-content/uploads/2013/02/android-musical2.jpg";
UniversalImageLoader.setImage( imgURL, profilePhoto, mProgressBar, "https://");
}
private void setupActivityWidgets(){
mProgressBar = findViewById(R.id.profileProgressBar);
mProgressBar.setVisibility(View.GONE);
profilePhoto = findViewById(R.id.profile_photo);
}
private void setupToolbar() {
Toolbar toolbar = findViewById(R.id.profileToolBar);
setSupportActionBar(toolbar);
ImageView profileMenu = findViewById(R.id.profileMenu);
profileMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(mContext, AccountSettingsActivity.class);
startActivity(intent);
}
});
}
/**
* BottomNavigationView setup
*/
private void setupBottomNavigationView() {
BottomNavigationViewEx bottomNavigationViewEx = findViewById(R.id.bottomNavViewBar);
BottomNavigationViewHelper.bottomNavigationView(bottomNavigationViewEx);
BottomNavigationViewHelper.enableNavigation(mContext, bottomNavigationViewEx);
Menu menu = bottomNavigationViewEx.getMenu();
MenuItem menuItem = menu.getItem(ACTIVITY_NUM);
menuItem.setChecked(true);
}
}
You must check that all the views that you are getting using findViewById() really exist into the activity_profile.xml layout.
One or more views doesn´t really exist, and you have a null value gettin the reference.
findViewById(R.id.profileProgressBar);
findViewById(R.id.profile_photo);
findViewById(R.id.profileToolBar);
findViewById(R.id.profileMenu);
findViewById(R.id.bottomNavViewBar);
initially you are not getting any error tryin to find the references of this views because they are really exist but in another layout but not in activity_profile.xml that you are loading via setContentView() in your Activity.
This type of exception rise at the time of the wrong variable declaration and
initialization.
Try this
replace your weighs declare and initialize val with var.
If you have to use java
final TextView helloTextView = (TextView)findViewById(R.id.text_view_id);
For Kotlin
val helloTextView = findViewById(R.id.text_view_id) as TextView
you can refer this link for more details

#XmlPath(".") conflicts with #XmlAdapter

having this Jaxb Xml definition, i try to remove the Map Elements Wrapper by adding #XmlPath(".") but it cause exception during the unmarchaling
#XmlRootElement
public abstract class ViewElement{
#XmlJavaTypeAdapter(value=EventAdapter.class)
public Map<Event, String> getEvents() {
}
private transient Class entityType;
public Class getEntityType() {
return entityType;
}
}
And the EventAdapter is
public class EventAdapter extends XmlAdapter<EventAdapter.AdaptedMap, Map<Event, String>> {
public static class AdaptedMap {
#XmlVariableNode("key")
List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();
}
public static class AdaptedEntry {
#XmlTransient
public String key;
#XmlValue
public String value;
}
.....
}
my output was
<element>
<events>
<onCellEdit>do some thing<onCellEdit>
</events>
<entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>
I try to remove the <events> tag by adding #XmlPath(".")
#XmlPath(".")
#XmlJavaTypeAdapter(value=EventAdapter.class)
public Map<Event, String> getEvents() {
}
The output is good
<element>
<onCellEdit>do some thing<onCellEdit>
<entityType>com.agitech.erp.model.erp.ErpFolder</entityType>
<element>
but the unmarchaling faileds
Caused by: Exception [EclipseLink-3002] (Eclipse Persistence Services - 2.6.0.v20140809-296a69f): org.eclipse.persistence.exceptions.ConversionException
Exception Description: The object [], of class [class java.lang.String], from mapping [org.eclipse.persistence.oxm.mappings.XMLDirectMapping[entityType-->view.entityType/text()]] with descriptor [XMLDescriptor(com.agitech.erp.view.BeanView --> [DatabaseTable(view), DatabaseTable(viewFrame), DatabaseTable(viewElement)])], could not be converted to [class java.lang.Class].
Internal Exception: java.lang.ClassNotFoundException:
at org.eclipse.persistence.exceptions.ConversionException.couldNotBeConvertedToClass(ConversionException.java:95)
at org.eclipse.persistence.internal.helper.ConversionManager.convertObjectToClass(ConversionManager.java:446)
Debuging Jaxb bring me to the line
org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue
public void endElement(XPathFragment xPathFragment, UnmarshalRecord unmarshalRecord) {
...
line 205 unmarshalRecord.setAttributeValue(convertedValue, xmlDirectMapping);
}
During the unmarchaling of entityType value, the UnmarshalRecordImpl.currentObj contains the EventAdapter instead of the parent element
I modify org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl
public XPathNode getNonAttributeXPathNode(String namespaceURI, String localName, String qName, Attributes attributes) {
....
if(null == resultNode && null == nonPredicateNode) {
// ANY MAPPING
resultNode = xPathNode.getAnyNode();
// by default it return the EventAdapter, changing it to NULL fix my problem
}
....
}
Not a safe solution
I have been able to reproduce the issue that you are seeing, but haven't yet worked out the cause. You can use the following bug to track the progress on this issue:
http://bugs.eclipse.org/457169
After trying a lot of things, I was able to find a workaround for this issue. I thought of posting here the same so it can be helpful to someone else in the future. The lead has confirmed the issue around 5 years ago but seems like they have not fixed it and I was facing a similar issue.
Basically, we can use the beforeMarshal and afterUnmarshal methods to change the values in the fields.
You need to create a field List<Object> with #XmlAnyElement(lax=true) along with Map<String,Object>.
Remove the #XmlPath(".") and the XMLAdapter class.
Mark the field Map<String, Object> with #XmlTransient.
Now within the beforeMarshal and afterMarshal fields, you can exchange the data. During the unmarshal in beforeunmarshal, all the unknown field values will be present within the List<Object> loop over it and add it to the Map<String, Object>.
Similarly during the marshaling, you can move the values Map<String, Object> to List<Object> by creating the DOM elements.
Marshaling all values are added to root as DOM Elements are present and during Unmarshaling known values are read first and then-unknown values are stored within List<Object> due to #XmlAnyElement.
I have created an example using the Customer class, you can modify it accordingly for your need.
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
#JsonInclude(Include.NON_NULL)
#JsonIgnoreProperties(ignoreUnknown = true)
#XmlRootElement(name = "Customer")
#XmlType(name = "Customer", propOrder = {"name", "age", "otherElements"})
#XmlAccessorType(XmlAccessType.FIELD)
#Getter
#Setter
#AllArgsConstructor
#ToString
#NoArgsConstructor
public class Customer {
#XmlTransient
private String isA;
private String name;
private String age;
#XmlAnyElement(lax = true)
#JsonIgnore
private List<Object> otherElements = new ArrayList<>();
#JsonIgnore
#XmlTransient
private Map<String, Object> userExtensions = new HashMap<>();
#JsonAnyGetter
#JsonSerialize(using = CustomExtensionsSerializer.class)
public Map<String, Object> getUserExtensions() {
return userExtensions;
}
#JsonAnySetter
public void setUserExtensions(String key, Object value) {
userExtensions.put(key, value);
}
private void beforeMarshal(Marshaller m) throws ParserConfigurationException {
System.out.println("Before Marshalling User Extension: " + userExtensions);
ExtensionsModifier extensionsModifier = new ExtensionsModifier();
otherElements = extensionsModifier.Marshalling(userExtensions);
System.out.println("Before Marshalling Final Other Elements " + otherElements);
userExtensions = new HashMap<>();
}
private void afterUnmarshal(Unmarshaller m, Object parent) throws ParserConfigurationException {
System.out.println("After Unmarshalling : " + otherElements);
ExtensionsModifier extensionsModifier = new ExtensionsModifier();
userExtensions = extensionsModifier.Unmarshalling(otherElements);
otherElements = new ArrayList();
}
}
You can refer the creation of DOM ELEMENTS here:https://stackoverflow.com/a/24239105/7584240
You can refer my complete answer here: https://stackoverflow.com/a/67923216/7584240

JavaFX access ui-elements from Controller(Singleton)

I have a javafx design in the file javafx.fxml where the root element has the following attribute
fx:controller="de.roth.jsona.javafx.ViewManagerFX"
This controller class has a singleton machanism and is binded with some ui-elements.
public class ViewManagerFX {
private static ViewManagerFX instance = new ViewManagerFX();
#FXML
private Slider volumeSlider;
#FXML
private Label volumeLabel;
public IntegerProperty volumeValue = new SimpleIntegerProperty();
#FXML
private TabPane musicTabs;
public List<StringProperty> tabNames = new ArrayList<StringProperty>();
public static ViewManagerFX getInstance() {
return (instance);
}
public void initialize() {
// Volume
volumeSlider.valueProperty().bindBidirectional(volumeValue);
volumeLabel.textProperty().bindBidirectional(volumeValue, new Format() {
#Override
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos) {
toAppendTo.append(obj);
toAppendTo.append("%");
return toAppendTo;
}
#Override
public Object parseObject(String source, ParsePosition pos) {
return null; // no need to be implemented
}
});
volumeValue.set(Config.getInstance().VOLUME);
}
public void addMusicFolderTab(final String t, final ArrayList<MusicListItem> items) {
Platform.runLater(new Runnable() {
#Override
public void run() {
Tab m = new Tab("Test Tab");
musicTabs.getTabs().add(0, m);
}
});
}
}
The method addMusicFolderTab is called from a thread that is used to scan files and directories.
In the initialize method I can access the ui-elements but in the method addMusicFolderTab, that is called from the filescanner-thread, the variable musicTabs is null. Here is the exception:
java.lang.NullPointerException
at de.roth.jsona.javafx.ViewManagerFX$3.run(ViewManagerFX.java:110)
I have no clue, why I can't access the TabPane from outside the initialize method.
Aside from the many questionable patterns used here, the problem is that your ViewManagerFX singleton (besides not being a singleton) never has its instance set.
When using FXML, the Controller is created and loaded dynamically by Reflection from the FXMLoader.
What happens is that by calling ViewManagerFX.getInstance(), you access the a different controller than the one created by the FXMLoader. The instance you access is the one created here:
private static ViewManagerFX instance = new ViewManagerFX();
The quickest way to solve the issue is to set the instance in the initialize() since it's called by the FXMLoader on the instance created by the FXMLoader.
public void initialize() {
instance = this;
// Volume
...
}

the specified child already has a parent .you must call removeView()

For some reason, I keep receiving the following error:
java.lang.IllegalStateException: the specified child already has a parent. You must call removeView() on the child's parent view
I am using the following code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listitem);
//url is fetched from another class
readWebpage(imdbUrl);
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
}
#Override
protected void onPostExecute(String result) {
//textView.setText(result);
displayMoviesList(result);
}
}
public void readWebpage(String imdbUrl) {
}
public void displayMoviesList(String result) {
JSONObject responseObj = null;
try {
responseObj = new JSONObject(result);
JSONObject Obj = responseObj.getJSONObject("results");
JSONArray moviesListObj = Obj.getJSONArray("result");
for(int i=0 ;i<moviesListObj.length();i++) {
JSONObject e = moviesListObj.getJSONObject(i);
cover[i] = e.getString("cover");
title[i] = e.getString("title");
year[i] = e.getString("year");
director[i] = e.getString("director");
rating[i] = e.getString("rating");
details[i] = e.getString("details");
}
tl = (TableLayout) findViewById(R.id.main_table);
imgView = (ImageView)findViewById(R.id.imageID);
progressbar = (ProgressBar) findViewById(R.id.loadingBar);
//new loadImageTask().execute(cover[i].toString());
new loadImageTask().execute( URL);// it calls another function..
TextView title = (TextView)findViewById(R.id.titleID);
title.setText("TEXT");
TableRow tr = new TableRow(this);
tr.addView(imgView);
tr.addView(title);
tl.addView(tr, new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
} catch(JSONException e) {
//Log.e("log_tag", "Error parsing data " + e.toString());
}
I am not sure why I'm receiving the error, but it appears to be being generated while I am adding it to the view.
Solution is that we either we define the rows in .xml file or in our .java file. I was adding the rows dynamically in my java file and using addView. So in .xml file we cannot add another view (we should not add rows for the same).

Alternative for cloning in LWUIT Component object

Situation:-
In my code I have to use the LWUIT Component object for the listview controls. The controls are dynamic and hence can be in any number.
Right now I am creating Component objects according to the controls(in numbers) i.e.- for every control to be created first the Component object is creating.
This process slows down the rendering of the listview when the controls are increasing.
Solution:-
If I create the Component object and use it in a loop for all the controls it is taking the reference of the object and hence displays all the listview items(controls) with the same data.
Now I am able to think of one last option of Cloning my object and using it to create the controls.
Problem:-
But I can't find any way in LWUIT by which I can achieve the copying of object.
What can be the alternatives in LWUIT to solve this problem?
P.S.-The listview items are of same type, but with different data.
Use a List component and the Renderer design pattern to create a "rubber stamp" component where you can display a large number of elements easily. See an explanation of this in the Codename One blog.
Create these classes first :
public class ListUtil {
private Vector data = new Vector();
private Content[] contents;
public ListUtil(Vector vData)
{
data = vData;
contents = new Content[vData.size()];
}
public List createList(Display display, CListCell renderer, ActionListener listener)
{
CList theList;
for(int i = 0; i < data.size(); i++)
{
contents[i] = new Content(String.valueOf(data.elementAt(i)));
}
theList = new CList(display, contents, renderer, listener);
return theList;
}
}
public class Content
{
private String row;
public Content(String row)
{
this.row = row;
}
public String getRow()
{
return (row);
}
}
public class CListCell extends Container implements ListCellRenderer {
private Label focus = new Label("");
public CListCell()
{
super();
// create and add the components here among the components which will display data
}
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
{
Content entry = null;
if (value instanceof Content)
entry = (Content)value;
componentDisplayingDataAddedIntoThisListCellRenderer.setText(entry.getRow());
return this;
}
public Component getListFocusComponent(List arg0)
{
return focus;
}
}
public class CList extends List {
private Display disp;
public CList(Display display, Object[] data, CListCell renderer, ActionListener actionListener)
{
super(data);
setListCellRenderer(renderer);
setIgnoreFocusComponentWhenUnfocused(true);
addActionListener(actionListener);
setScrollAnimationSpeed(getScrollAnimationSpeed()/4);
disp = display;
}
public void pointerReleased(int x,int y)
{
if (isEnabled() && hasFocus())
super.pointerReleased(x, y);
}
public void keyReleased(int keyCode)
{
if (isEnabled() && hasFocus())
{
if (disp.getGameAction(keyCode) == Display.GAME_FIRE)
pointerReleased(getX(),getY());
else
super.keyReleased(keyCode);
}
}
}
To create your List and add it to a Form :
public class myForm extends Form implements ActionListener
{
private Vector listSource = // your vector of data
private CListCell renderer = new CListCell();
private List theList = (new ListUtil(listSource)).createList(Display.getInstance(),renderer, this);
...
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == theList)
doSomething();
}
}

Resources