Android studios how to pass a context from mainactivity to another class - java

I have this problem, how do i use a function from MainActivity in my class Dialog_findname, i have to pass the context of main in line: vardadienas = main.loadedfile(MainActivity.this);
public class Dialog_findname extends AppCompatDialogFragment {
private EditText findName;
private findnameDialogListener listener;
private List<VDienas> vardadienas = new ArrayList<>();
private Finder finder = new Finder();
private MainActivity main = new MainActivity();
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
vardadienas = main.loadedfile(MainActivity.this);
}
And this is my MainActivity function I want to call in the other class:
public List<VDienas> loadedfile(Context ctxt){
FileInputStream fis = null;
try {
fis = openFileInput(FILE_NAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader reader = new BufferedReader(isr);
String line;
reader.readLine();
while ((line = reader.readLine()) != null){
VDienas VissGads = new VDienas();
String[] tokens = line.split(";");
VissGads.setDatums(tokens[0]);
VissGads.setMenesis(Integer.parseInt(tokens[1]));
VissGads.setDiena(Integer.parseInt(tokens[2]));
for (int i = 0; i < Integer.parseInt(tokens[3]); i++) {
VissGads.setVards(tokens[i + 4]);
}
vardadienas.add(VissGads);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return vardadienas;
}
I tried to look up for similar questions, but i still couldn't understand how to :(

First, you can't create an Activity with the following:
private MainActivity main = new MainActivity();
it should be started with Context.startActivity(), you can read more about it at Activity documentation.
Second, you have the following method:
public List<VDienas> loadedfile(Context ctxt) {
...
}
so, you can't call it with the following inside of Fragment:
vardadienas = main.loadedfile(MainActivity.this);
because MainActivity.this is referencing to instance of MainActivity but your fragment is not an instance of activity.
You need to call the method with the following:
vardadienas = main.loadedfile(getContext());
where getContext() referring to Activity where the Fragment attached.
You better move the loadedfile(Context ctxt) to its own class as an util class so you can reuse the method from any other class. You can make something like this:
public class FileUtils {
private FileUtils() {} // this prevent class being instantiate.
// we need to make it static so it can be accessed without
// creating an instance of the class.
// of course, you can use singleton. But it's another topic
public static List<VDienas> loadedfile(Context ctxt) {
...
}
}
then you can use the method with something like this:
vardadienas = FileUtils.loadedfile(getContext());

i think, u have to call this Function on ur MainActivity.
vardadienas = main.loadedfile(this);
or check MainActivity.class

Related

errors when static and when not static (specific)

I know the title doesn't say much, but I have a pretty specific problem that is difficult to describe:
I'm making an android app with Android Studio, and for one activity I have a list where the values that are stored in a json file will go.
For getting these values I use another class with a get() method which returns the values in an arraylist. The problem is that the IDE says 2 contrary statements: in the activity class it says that the get() method has to be static and in the other class it says that the get() method can't be static.
This is the code:
CompanySelector.java (the activity)
public class CompanySelector extends AppCompatActivity {
ArrayList<String> companyList = CompanyStorage.get();
}
==> here it gives an error in CompanyStorage.get() and says that get() should be static.
CompanyStorage.java (the other class)
abstract class CompanyStorage extends Context {
private ArrayList<String> companyList;
protected CompanyStorage() throws JSONException {
companyList = get();
}
ArrayList<String> get() throws JSONException {
JSONObject companyData = new JSONObject();
ArrayList<String> companyList = new ArrayList<>();
// Open data.json and convert to JSONObject
String json = OpenFileAsString("data.json");
try {
companyData = new JSONObject(json);
} catch (JSONException e) {
e.printStackTrace();
}
// return json array as ArrayList
if (companyData.getJSONArray("companies") != null) {
for (int i=0;i<companyData.getJSONArray("companies").length();i++){
companyList.add(companyData.getJSONArray("companies").getString(i));
}
}
return companyList;
}
public String OpenFileAsString(String filename) {
try {
InputStream stream = getAssets().open( filename );
int size = stream.available();
byte[] bytes = new byte[size];
stream.read(bytes);
stream.close();
return new String( bytes );
} catch ( IOException e ) {
Log.i("GuiFormData", "IOException: " + e.getMessage() );
}
return null;
}
}
==> Here it says that if get() is static, OpenFileAsString() should also be static, but then it gives an error, because getAssets() can't be in a static method.
Does anyone know what I should do? I'm fairly new to Java and application design..
Try to put static at the get() and OpenFileAsString(String filename) methods header and use context.getAssets() instead of getAssets()

Cloning data between two objects with a field sorted set Java

Ok so i have two classes: Content and TrackUserChanges . They have the same fields.
public class Content{
private Long id;
......
private SortedSet<Content> children = new TreeSet<Content>();
}
public class TrackUserChanges{
private Long id;
.....
private SortedSet<Content> children = new TreeSet<Content>();
}
I want to clone the data from Content to TrackUserChanges:
I have the children from an instance of content:
SortedSet<Content> children = content.getChildren();
This can contain many other contents, and that contents can have also children, etc.
SortedSet<TrackUserChanges> children1 = convertContentSetToTrackUserChangesSet(children);
This is the method:
public SortedSet<TrackUserChanges> convertContentSetToTrackUserChangesSet(SortedSet<Content> children){
SortedSet<TrackUserChanges> children1 = new TreeSet<TrackUserChanges>();
for(Content c : children){
TrackUserChanges trackU = new TrackUserChanges();
trackU.setCategory(c.getCategory());
trackU.setId(c.getId());
trackU.setBook(c.getBook());
trackU.setInsertUser(c.getInsertUser());
trackU.setParent(c.getParent());
trackU.setParentId(c.getParentId());
trackU.setRelativeSortOrder(c.getRelativeSortOrder());
trackU.setText(c.getText());
trackU.setType(c.getType());
children1.add(trackU);
}
return children1;
}
I need somehow to call recusively or something like that... and I can't do trackU.setChildren(c.getChildren()) because the types don't match :/
#Mifmif
try {
FileOutputStream fout = new FileOutputStream("a.dat");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(content);
oos.close();
}
catch (Exception e) { e.printStackTrace(); }
TrackUserChanges trackUserChanges11 = new TrackUserChanges();
try {
FileInputStream fin = new FileInputStream("a.dat");
MyCustomObjectInputStream custom = new MyCustomObjectInputStream(fin);
// custom.readClassDescriptor();
trackUserChanges11 = (TrackUserChanges) custom.readObject();
System.out.println("IDDDDD" + trackUserChanges11.getId());
custom.close();
}
catch (Exception e) { e.printStackTrace(); }
ClassCastException :)
If you have two classes with identical properties that have identical behaviour, separate those fields/behaviour into a separate class and extend that class in your other classes. This should allow you to copy directly between them.
Make your class implements Cloneable. Then just call the function clone of the SortedSet.
http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html
Here is a solution based on serialization , make both of your class serializable and if you want to go from one class instance to another, serialize your instance into a file , and read it using MyCustomObjectInputStream :
class MyCustomObjectInputStream extends ObjectInputStream {
public MyCustomObjectInputStream(InputStream in) throws IOException {
super(in);
}
#Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("name.of.the.package.OldClassName"))
resultClassDescriptor = ObjectStreamClass.lookup(name.of.the.package.NewClassName.class);
return resultClassDescriptor;
}
}
I resolved the problem
public TrackUserChanges convertContentToTrack(Content c) {
TrackUserChanges t = new TrackUserChanges();
t.setCategory(c.getCategory());
t.setId(c.getId());
t.setBook(c.getBook());
t.setInsertUser(c.getInsertUser());
t.setParent(c.getParent());
t.setParentId(c.getParentId());
t.setRelativeSortOrder(c.getRelativeSortOrder());
t.setText(c.getText());
t.setType(c.getType());
if (c.getChildren().size() == 0) {
return t;
}
SortedSet<TrackUserChanges> childs = new TreeSet<TrackUserChanges>();
for (Content content : c.getChildren()) {
childs.add(convertContentToTrack(content));
}
t.setChildren(childs);
return t;
}
Thanks anyway :)

How to use ArrayList while adding something to another Class's constructor ?

I'm try to create one simple reservation system, we'll read a file, then we'll add Train, Bus, etc., then we'll writer everything to output.
import java.io.*;
import java.util.*;
public class Company
{
private static ArrayList<Bus> bus = new ArrayList<Bus>();
static int buscount = 0, traincount = 0;
public static void main (String[] args) throws IOException
{
FileParser();
}
public Company()
{
}
public static void FileParser()
{
try {
File file = new File(); //i fill this later
File file2 = new File(); // i fill this later
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file2);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
String line;
while ((line = br.readLine()) != null)
{
String[] splitted = line.split(",");
if(splitted[0].equals("ADDBUS"))
{
bus.add(buscount) = Bus(splitted[0],splitted[1],splitted[2],splitted[3],splitted[4],splitted[5]);
}
}
}
catch (FileNotFoundException fnfe) {
}
catch (IOException ioe) {
}
}
}
I try to read the file line by line. For example one of the line is "ADDBUS,78KL311,10,140,54" I split the line for "," then i try to add every pieces of array to Bus' class' constructor but i couldn't figured it out.
My Bus Class is like `
public class Bus extends Vehicle{
private String command;
private String busName;
private String busPlate;
private String busAge;
private String busSpeed;
private String busSeat;
public Bus(String command, String busname, String busplate, String busage, String busspeed, String busseat)
{
this.command = command;
this.busName = busname;
this.busPlate = busplate;
this.busAge = busage;
this.busSpeed = busspeed;
this.busSeat = busseat;
}
public String getBusName() {
return busName;
}
public void setBusName(String busName) {
this.busName = busName;
}
public String getBusPlate() {
return busPlate;
}
public void setBusPlate(String busPlate) {
this.busPlate = busPlate;
}
public String getBusAge() {
return busAge;
}
public void setBusAge(String busAge) {
this.busAge = busAge;
}
public String getBusSpeed() {
return busSpeed;
}
public void setBusSpeed(String busSpeed) {
this.busSpeed = busSpeed;
}
public String getBusSeat() {
return busSeat;
}
public void setBusSeat(String busSeat) {
this.busSeat = busSeat;
}
public String getCommand() {
return command;
}
public void setCommand(String command) {
this.command = command;
}
}
can someone show me a way to solve this problem?
Thank you,
You are missing the keyword new to create a new instance of the class:
bus.add(new Bus(...));
You can add items to ArrayList like this
bus.add( new Bus(splitted[0],splitted[1],splitted[2],splitted[3],splitted[4],splitted[5]));
you were missing new keyword before Bus constructor call. Then you can increment the counter (or do whatever)
bus.add( new Bus(splitted[0],splitted[1],splitted[2],splitted[3],splitted[4],splitted[5]));
buscount++;
try to add new Bus(...)
bus.add( new
Bus(splitted[0],splitted[1],splitted[2],splitted[3],splitted[4],splitted[5]));
As I understand if you want to call constructor you need to call new Bus(parms).
when you say new it will call constructor of your class
when you say this() again it going to call enclosing class' constructor
if you say super() it will call super class' constructor.
if you want it into a map order by counter you can use this:
Map(Integer, Bus) busPosition = new HashMap<>();
busPosition.put(buscount, new
Bus(splitted[0],splitted[1],splitted[2],splitted[3],splitted[4],splitted[5]));

Adding an ArrayList created in a method to JCombobox

I've asked a similar question before, but realised the main issue at hand which I cannot solve:
Currently have an ArrayList called SundayList which is loaded as soon as the frame AddStudent is loaded (bit of GUI)
The Add Student class:
Edited
public class AddStudent extends javax.swing.JFrame {
public AddStudent() {
initComponents();
}
private void loadLists() throws IOException
{
//Creating the array of Activities to put into the ComboBoxes
File f = new File("Activities.dat");
sundayList = new ArrayList<>();
mondayList= new ArrayList<>();
tuesdayList= new ArrayList<>();
wednesdayList= new ArrayList<>();
thursdayList= new ArrayList<>();
try{
BufferedReader reader = new BufferedReader(new FileReader(f));
while(reader.ready())
{
String CDay = reader.readLine();
String CActivityName = reader.readLine();
String CSupervisor = reader.readLine();
String CLocation = reader.readLine();
String CPaid = reader.readLine();
String nothing = reader.readLine();
if(CDay.equals("Sunday"))
{
sundayList.add(CActivityName);
}
else if(CDay.equals("Monday"))
{
mondayList.add(CActivityName);
}
else if(CDay.equals("Tuesday"))
{
tuesdayList.add(CActivityName);
}
else if(CDay.equals("Wednesday"))
{
wednesdayList.add(CActivityName);
}
else if(CDay.equals("Thursday"))
{
thursdayList.add(CActivityName);
}
}
reader.close();
}
catch (IOException ex)
{
Logger.getLogger(StartUpFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
...
comboboxSunday = new javax.swing.JComboBox();
...
}
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AddStudent().setVisible(true);
}
});
}
For a start,I've tried to call the list SundayList into the combo box comboboxSunday to populate it, but only got the cannot find symbol error.
What do I need to do to make this possible?
Also, I plan on avoiding the mySQL involved method I've seen before, as I'm not familiar with it..
Current Coding for Combo box
The code automatically generated for the combo box by Netbeans is:
comboboxSunday = new javax.swing.JComboBox();
comboboxSunday.setModel(new javax.swing.DefaultComboBoxModel<>(sundayList.toArray(new String[sundayList.size()])));
The variable SundayList is limited to the scope of your constructor. Assuming you are creating your JComboBox in your initComponents method, you will not be able to access this variable.
You could however make SundayList a class member variable allowing you to use the variable accross methods. Also better to have a method to load data rather than having non-UI functionality in a UI constructor:
public class AddStudent {
private List<String> sundayList;
private List<String> mondayList;
...
private void loadLists() throws IOException {
sundayList = new ArrayList<>();
...
Then to add:
comboboxSunday.setModel(new DefaultComboBoxModel<>(sundayList.toArray(new String[sundayList.size()])));
Don't forget to call your new load method:
AddStudent addStudent = new AddStudent();
addStudent.loadLists();
addStudent.setVisible(true);
Aside: note that Java naming conventions indicate that variable start with a lowercase letter which would make SundayList sundayList.

Android, can I put AsyncTask in a separate class and have a callback?

I'm just learning about AsyncTask and want to use it as a separate class, rather then a subclass.
For example,
class inetloader extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(urls[0]);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(String result) {
Log.e("xx",result);
// how do I pass this result back to the thread, that created me?
}
}
and the main(ui) thread:
inetloader il = new inetloader();
il.execute("http://www.google.com");
//il.onResult()
//{
///do something...
//}
Thanks!
Use a interface. Something like:
interface CallBackListener{
public void callback();
}
Then do this in your UI thread:
inetloader il = new inetloader();
li.setListener(this);
il.execute("http://www.google.com");
In inetloader, add:
CallBackListener mListener;
public void setListener(CallBackListener listener){
mListener = listener;
}
then In postExecute(), do:
mListener.callback();
you can pass the activity instance to constructor and call activity function from there...
Like use interface :
public interface ResultUpdatable {
public void setResult(Object obj);
}
Implement this in the Activity and pass in the constructor of Async task and update the result from onPostExecute using setResult function.
inetloader il = new inetloader();
il.execute("http://www.google.com");
String result = il.get();//put it in try-catch
^^^^^^^^
here you get result which is in onPostExecute(String result)

Categories

Resources