Nullpointerexception when trying to use interface to pick up data from one Ragment to another

Asked

Viewed 58 times

2

I’m doing a program that creates graphs, that contains a page with two tab Fragments one for the graph and another for the algorithms I’m trying to make when a button is clicked on the algorithms Fragment send a request to the graph where the algorithm is executed and returns a string that I placed on the screen of the Fragment algorithms, however if I try to use any data from Fragment graph this returned Null Pointer Exception.

this is Tab:

public class Tab extends AppCompatActivity implements DialogAddAresta.ExampleDialogListner,
        DialogDeletar.DeletarElementos, FragmentAlgoritmo.Communicator{

    private FragmentGrafo fragmentGrafo = new FragmentGrafo();
    private FragmentAlgoritmo fragmentAlgoritmo = new FragmentAlgoritmo();

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

        TabLayout tabLayout = findViewById(R.id.tablayout_id);
        ViewPager viewPager = findViewById(R.id.viewpager_id);

        ViewPageAdapter adapter = new ViewPageAdapter(getSupportFragmentManager());
        adapter.AddFragment(new FragmentGrafo(), "Grafo");
        adapter.AddFragment(new FragmentAlgoritmo(), "Algoritmo");

        viewPager.setAdapter(adapter);
        tabLayout.setupWithViewPager(viewPager);
    }
    @Override
    public void applyNodes(String selectedNodeTo, String selectedNodeFrom, String peso) {
    }
    @Override
    public void applyDeletar(String deletaNo,String deltaAresta, boolean controle) {
    }
    @Override
    public void onEvent(Event e) {
        if (e.getType() == Event.Type.CLICK){
            fragmentGrafo.primeiroNo();
        } else {
            String data = e.getString();
            fragmentAlgoritmo.colocaElem(data);
        }
    }
}

this is the fragment:

public class FragmentGrafo extends Fragment  implements DialogAddAresta.ExampleDialogListner, DialogDeletar.DeletarElementos {

    private static final int CONTENT_VIEW_ID = 10101010;
    private DefaultFragment fragment;
    private Graph graph;
    private String[] criaNos = new String[]{"A","B","C","D","E","F","G","H","I","J","K",
            "L","M","N","O","P","Q","R","S","T","U","V","X","W","Y","Z"};
    private int pos = 0;
    private float x = 0.0f;
    private float y = 0.0f;
    private String styleSheet = "graph { fill-color: #EEE; }" +
            "node { size: 100px; text-size: 30px; fill-color: white; stroke-mode: plain;}" +
            "node:clicked {fill-color: blue;}"+
            "edge { size: 5; text-size: 30px; padding: 0, 12;}";
    List<String> nos = new ArrayList<>();
    private List<String> arestas = new ArrayList<>();
    String[] st = new String[]{"texte","macaco"};
    FragmentAlgoritmo fragmentAlgoritmo = new FragmentAlgoritmo();
    FragmentAlgoritmo.Communicator listner;

    public FragmentGrafo(){
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       final View view = inflater.inflate(R.layout.grafo_fragment, container, false);
       return view;
    } 
    @Override
    public void onCreate(@Nullable android.os.Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.setProperty("org.graphstream.ui.renderer", "org.graphstream.ui.j2dviewer.J2DGraphRenderer");
        graph = new MultiGraph("AthenaGraph");

        graph.setAttribute( "ui.stylesheet", styleSheet);
        graph.setAttribute("ui.antialias");

        display(savedInstanceState, graph, false);
    }

    public void display(Bundle savedInstanceState, Graph graph, boolean autoLayout) {
        if (savedInstanceState == null) {
            FragmentManager fm = getActivity().getFragmentManager();
            fragment = (DefaultFragment) fm.findFragmentByTag("fragment_tag");

            if (null == fragment) {
                fragment = new DefaultFragment();
                fragment.init(graph, autoLayout);
            }

            FragmentTransaction ft = fm.beginTransaction() ;
            ft.add(R.id.layoutFragment, fragment).commit();
        }
    }

    public void openDialogAddAresta() {
        DialogAddAresta dialogAddAresta = new DialogAddAresta();

        Bundle bundle = new Bundle();
        bundle.putStringArrayList("list", (ArrayList<String>)nos);

        dialogAddAresta.setArguments(bundle);
        dialogAddAresta.setTargetFragment(FragmentGrafo.this, 1);
        dialogAddAresta.show(getActivity().getSupportFragmentManager(), "Add Aresta");
    }

    public void openDialogDeletar(){
        DialogDeletar dialogDeletar = new DialogDeletar();

        Bundle bundle = new Bundle();
        bundle.putStringArrayList("listArestas", (ArrayList<String>)arestas);
        bundle.putStringArrayList("listNos", (ArrayList<String>)nos);

        dialogDeletar.setArguments(bundle);
        dialogDeletar.setTargetFragment(FragmentGrafo.this, 1);
        dialogDeletar.show(getActivity().getSupportFragmentManager(), "Deletar");
    }
    public void primeiroNo(){
        String s = graph.getNode(0).getId();
        listner.onEvent(new Event(s , Event.Type.DISPATCH));
    }

    public String pegaNos(){
        StringBuilder string= new StringBuilder();
        for (Node n : graph){
            string.append(n);
        }
        return string.toString();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof FragmentAlgoritmo.Communicator) {
            try {
                listner = (FragmentAlgoritmo.Communicator) context;
            } catch (ClassCastException e) {
                throw new ClassCastException(context.toString() + "deve implementar Algoritmos");
            }
        }
    }
}

this is the fragment:

public class FragmentAlgoritmo extends Fragment {

    private Spinner spAlgo;
    private ImageButton btnRun, btnExecutar;
    private ImageView imageView;
    private TextView textView;
    private String testo;
    boolean run = true;

    private List<String> list;
    private Communicator listner;

    public FragmentAlgoritmo() {
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.algoritmo_fragment, container, false);

        spAlgo = view.findViewById(R.id.spAlgo);
        btnExecutar = view.findViewById(R.id.btn_executar);
        btnRun = view.findViewById(R.id.btn_run);
        imageView = view.findViewById(R.id.imageView);
        textView = view.findViewById(R.id.tvLinha1);

        ArrayAdapter<String> listAlgo = new ArrayAdapter<>(getActivity(), android.R.layout.simple_spinner_item, getResources().getStringArray(R.array.algoritmos) );
        listAlgo.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        spAlgo.setAdapter(listAlgo);

        btnRun.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (run){
                    btnRun.setImageResource(R.drawable.ic_run_slow_white_24dp);
                    Toast.makeText(getContext(), "Velocidade reduzida", Toast.LENGTH_SHORT).show();
                    run = false;
                } else {
                    btnRun.setImageResource(R.drawable.ic_run_fast_white_24dp);
                    Toast.makeText(getContext(), "Velocidade normal", Toast.LENGTH_SHORT).show();
                    run = true;
                }
            }
        });

        btnExecutar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                switch (testo){
                    case "***":
                        Toast.makeText(getContext(), R.string.selecione_func, Toast.LENGTH_SHORT).show();
                        break;
                    case "Dijkstra":
                        listner.onEvent(new Event(null, Event.Type.CLICK));
                        break;
                    case "Coloração":
                        Toast.makeText(getContext(), "Coloração", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });

        spAlgo.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                testo = spAlgo.getItemAtPosition(position).toString();
                switch (testo){
                    case "***":
                        imageView.setVisibility(View.GONE);
                        textView.setText(R.string.selecione_func);
                        break;
                    case "Dijkstra":
                        imageView.setImageResource(R.drawable.dijkstra_alog);
                        imageView.setVisibility(View.VISIBLE);
                        textView.setText("Algo Aqui");
                        break;
                    case "Coloração":
                        imageView.setImageResource(R.drawable.under_construction);
                        imageView.setVisibility(View.VISIBLE);
                        textView.setText("Ainda sobre construção");
                        break;
                }
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        return view;
    }

    public void colocaElem(String s){
        textView.setText(s);
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof Communicator) {
            try {
                listner = (Communicator) context;
            } catch (ClassCastException e) {
                throw new ClassCastException(context.toString() + "deve implementar Algoritmos");
            }
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listner = null;
    }

    public interface Communicator {
        void onEvent(Event e);
    }

}

this is the Event

public class Event {
    public String string;
    public Type type;

    public Event( String string, Type type) {
        this.string = string;
        this.type = type;
    }

    enum Type { CLICK, DISPATCH }

    public String getString() {
        return string;
    }

    public Type getType() {
        return type;
    }

    public void setString(String string) {
        this.string = string;
    }
}

java.lang.Nullpointerexception: Attempt to invoke interface method 'org.graphstream.Graph.Node org.graphstream.Graph.Graph.getNode(int)' on a null Object Reference Fragmentgraph.primeirono(Fragmentgraph.java:202) Tab.onEvent(Tab.java:43) at com.projecto.Abriel.athenatgfinal.Fragmentalgoritmo$2.onClick(Fragmentalgoritmo.java:84) at android.view.View.performClick(View.java:5637) at android.view.View$Performclick.run(View.java:22429) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.Activitythread.main(Activitythread.java:6169) at java.lang.reflect.Method.invoke(Native Method) at com.android.Internal.os.Zygoteinit$Methodandargscaller.run(Zygoteinit.java:891) at com.android.Internal.os.Zygoteinit.main(Zygoteinit.java:781)

this method I’m doing this right? have any easier? please help me.

  • Always try to place the error stack so that we can analyze it better to help you.

  • put the error log, I can get from Fragment to the parent and call the other Fragment but ai da null nos methods, if I pass a string determined within the method works.

1 answer

1

I believe your problem can be solved by implementing the standard Communicator. The flow between the Fragments should always go through Activity. I will omit parts of your code to clarify the answer.

1 - First create the interface with the method for communication

public interface Communicator {
       public void onEvent(Event e);
}

2 - Create the class Event encapsulating data relating to communication

public class Event {
   public String data;
   public Type type;

   public Event(Type type, String data) {
      this.type = type;
      this.data = data;
   }

   public String getData() {
      return data;
   }

   enum Type { CLICK, DISPATCH }
}

3 - Make your Activity implement the interface Communicator

 public class Tab extends AppCompatActivity implements DialogAddAresta.ExampleDialogListner, 
DialogDeletar.DeletarElementos, 
FragmentAlgoritmo.Algoritmos, 
Communicator {

    /* ... */

   @Override
   public void onEvent(Event e) {
       if(e.getType() == Event.Type.CLICK) {
           // Chame seu fragmento do algoritmo aqui
       } else {
           // Você deve passar dados para o Fragment via Bundle e recuperá-los no método onCreate do fragmento
          String data = e.getData();
          Bundle bundle = new Bundle();
                 bundle.putString("chave_pra_recuperar_no_fragment", data);

          FragmentAlgoritmo fragobj = new Fragmentclass();
                            fragobj.setArguments(bundle);
          FragmentTransaction ft = fm.beginTransaction();
                              ft.replace(R.id.fragment_content, fragobj);
                               ft.commit();
       }
   }
}

4 - For both of them Fragments overrides the method onAttach

public FragmentName extend Fragment {
   private Communicator listener;

  /*...*/

  public void onAttach(Activity activity){
     try {
        listener = (Communicator) activity;
     } catch(Exception e) {
        throw Exception(activity.getSimpleName() + " deve implementar a interface Communicator");
     }
  }
}

5 - Handle button click events and issue Event to the Acivity

@Override
public void onClick(View v) {
   if(v.getId() == R.id.o_id_do_se_botao) {
      // Referência da interface de comunicação
      listener.onEvent(new Event(Event.Type.CLICK, null));
   }
}

6 - In your Fragment of the graph, insert a button and add to it a listener clique

private Button btGenerateGraph;

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
        View view = /*...*/;

        btGenerateGraph = (Button) view.findById(R.id.id_do_botao);
        btGenerateGraph.setOnClickListener(this);

        /*...*/
        return view;
    }

 @override
 public void onClick(View v) {
    if(v.getId() == R.id.id_do_botao) {
       String node = primeiroNo(); 
       listener.onEvent(new Event(Event.Type.DISPACTH, node));
    }
 }

I advise you to take a look at the documentation and see how the Fragments.

https://developer.android.com/training/basics/fragments/creating

  • I followed what you said and I managed to get inside the other Ragment but this giving the null meso error, I changed the code what I did fits what you said? or there’s something wrong.

  • Good evening @Gabrielricardo. Apparently at String s = graph.getNode(0).getId();, graph is void.

  • Ah, yes.. Because you’re calling the method primeiroNo() directly on Acitivity. The ideal would be for you to create a button on fragment and add a click event on it. When the event is added, you call the feature primeiroNo() and passes the return to listener.onEvent()

  • I edited my answer to fit your problem, reread it

Browser other questions tagged

You are not signed in. Login or sign up in order to post.