Frage

I have the following Java class:

package openDIS;

import java.net.*;
import java.applet.*;
import java.awt.*;

import edu.nps.moves.disutil.*;
import edu.nps.moves.dis.*;

/*Receives PDUs from the network in IEEE format. */

public class EspduReceiver {

/*Max size of a PDU in binary format that can be received. Outdated- PDUs can be larger- but this is a reasonable starting point */
public static final int MAX_PDU_SIZE = 8192;

/*Retrieve PDU data for use by class methods */
MulticastSocket socket;
DatagramPacket packet;
InetAddress address;
PduFactory pduFactory = new PduFactory();


public static void main(String args[]){

    MulticastSocket socket;
    DatagramPacket packet;
    InetAddress address;
    PduFactory pduFactory = new PduFactory();

    try{
        /*Specify the socket to receive the data */
        socket = new MulticastSocket(EspduSender.PORT);
        address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
        socket.joinGroup(address); 

        /*Loop infinitely, receiving datagrams */
        while(true){
            byte buffer[] = new byte[MAX_PDU_SIZE];
            packet = new DatagramPacket(buffer, buffer.length);

            socket.receive(packet);

            Pdu pdu = pduFactory.createPdu(packet.getData()); /*    Commented on 15/04/2014 @ 09:15 */

            if(pdu != null){
                System.out.print("Got PDU of type: " + pdu.getClass().getName());
                if(pdu instanceof EntityStatePdu){
                    EntityID eid = ((EntityStatePdu)pdu).getEntityID();
                    Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
                    System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                    System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]");
                } else if(!(pdu instanceof EntityStatePdu)){
                    System.out.println("There are no PDUs currently being received.");
                }
                System.out.println();
            }
        } /*end while */
    } /*end try */
    catch(Exception e){
        System.out.println(e);
        e.printStackTrace();
        System.out.println("This is where the error is being generated");
        /*09/04/2014 @ 17:100
         * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
         * that pdu does not actually hold a packet.  */
    }
} /*end main */

/*Create an 'Inner Class' (use as a C struct) to hold all of the variables pertaining to each PDU- each instance of the class
 * will hold a separate PDU. 
 * Create a method in Gui.java that will retrieve each instance of the inner class, and display the values on screen.*/

public class PDU{

    public String entityID;
    public double xLocation;
    public double yLocation;
    public double zLocation;
}



} /*end class */

When I run the class, it is currently working exactly as I'd intended- and I continually get messages printed to the console displaying information about the PDUs being sent across the network, for as long as I leave it running.

However, I now want to access the information about the messages being sent over the network that this class is reading and displaying in the console, from another class- my Gui class, so that I can present this information to the user.

As I understand, in order for another class to be able to access the information collected by this class, I will need to define a method outside of my main method, and put all of this code into that method- as other classes cannot access another class' main method? Is this correct? Then call the new method from inside my main method?

I have done this by taking all of the code from inside my main method (as it is above) and putting it inside the following method instead: public void receivePdu(){...}

I am then trying to call the receivePdu() method from my main method using the line receivePdu();, but I get an error that says "Cannot make a static reference to the non- static method receivePdu() from the type EspduReceiver", and suggests that I change modifier of 'receivePdu()' to 'static'".

If I go ahead and make the change it recommends- that breaks the code in my receivePdu() method, which is now a public static void method, and I get a load of errors such as "Cannot make a static reference to the non-static field socket, address, packet, pduFactory".

Does anyone know why I'm getting the error on my receivePdu(); call inside my main method, and how I should be doing it instead?

Thanks!

Edit 16/04/2014 @ 11:35

As mentioned originally, I have moved all of the code from the main method to another method called receivePdu(), and am now just calling that method from the main instead- I've added the updated code below:

package openDIS;

import java.net.*;
import java.applet.*;
import java.awt.*;

import edu.nps.moves.disutil.*;
import edu.nps.moves.dis.*;

/*Receives PDUs from the network in IEEE format. */

public class EspduReceiver {

/*Max size of a PDU in binary format that can be received. Outdated- PDUs can be larger- but this is a reasonable starting point */
public static final int MAX_PDU_SIZE = 8192;

/*Retrieve PDU data for use by class methods */
MulticastSocket socket;
DatagramPacket packet;
InetAddress address;
PduFactory pduFactory = new PduFactory();

public void receivePdu(){

    try{
        /*Specify the socket to receive the data */
        socket = new MulticastSocket(EspduSender.PORT);
        address = InetAddress.getByName(EspduSender.DEFAULT_MULTICAST_GROUP);
        socket.joinGroup(address); 

        /*Loop infinitely, receiving datagrams */
        while(true){
            byte buffer[] = new byte[MAX_PDU_SIZE];
            packet = new DatagramPacket(buffer, buffer.length);

            socket.receive(packet);

            Pdu pdu = pduFactory.createPdu(packet.getData()); /*    Commented on 15/04/2014 @ 09:15 */

            if(pdu != null){
                System.out.print("Got PDU of type: " + pdu.getClass().getName());
                if(pdu instanceof EntityStatePdu){
                    EntityID eid = ((EntityStatePdu)pdu).getEntityID();
                    Vector3Double position = ((EntityStatePdu)pdu).getEntityLocation();
                    System.out.print(" EID:[" + eid.getSite() + ", " + eid.getApplication() + ", " + eid.getEntity() + "] ");
                    System.out.print(" Location in DIS coordinates: [" + position.getX() + ", " + position.getY() + ", " + position.getZ() + "]");
                } else if(!(pdu instanceof EntityStatePdu)){
                    System.out.println("There are no PDUs currently being received.");
                }
                System.out.println();
            }
        } /*end while */
    } /*end try */
    catch(Exception e){
        System.out.println(e);
        e.printStackTrace();
        System.out.println("This is where the error is being generated");
        /*09/04/2014 @ 17:100
         * If this exception gets called, presumably it either means that pdu is not an instance of EntityStatePdu, or
         * that pdu does not actually hold a packet.  */
    }
}

public static void main(String args[]){

    receivePdu();

} /*end main */

/*Create an 'Inner Class' (use as a C struct) to hold all of the variables pertaining to each PDU- each instance of the class
 * will hold a separate PDU. 
 * Create a method in Gui.java that will retrieve each instance of the inner class, and display the values on screen.*/

public class PDU{

    public String entityID;
    public double xLocation;
    public double yLocation;
    public double zLocation;
}



} /*end class */

The issue that I am having is that I get the error "Cannot make a static reference to the non-static method receivePdu() from the type EspduReceiver", however, if I do what Eclipse suggests, and change the modifier of 'receivePdu(); to 'static', I get a load of other errors because nothing else is static.

I do not want anything to be static, because I need to reference the methods in this class from other classes in my program. Any suggestions what I can do to resolve this?

War es hilfreich?

Lösung

There is one main methode in one of your classes which is the starting point of the program. It is a good practise to seperate gui, data and logic.

So in your case I would do the following design.

class Main - contains your main methode which starts either GUI or CMD mode

class EspduReceiverGUI - Your GUI class for input/output

class EspduReceiver - which implements an interface EspduData

interface EspduData - which defines a methode getPDUData()

class PDU - Data class object

Then it will look something like this:

//Startpoint
public class Main
{
    public static void main(String[] args)
    {
         new EspduReceiverGUI();    //start gui somehow
    }
}

//GUI
public class EspduReceiverGUI
{
    //only exists once
    private static EspduData handler;

    //Get your Data and do something with it
    public EspduReceiverGUI()
    {
         handler = new EspduReceiver();
         PDU data = handler.getPDUData();

         doSomething(data);
    }
}

//Receiver
public class EspduReceiver implements EspduData
{
    //Variablen, Sockets etc.

    public PDU getPDUData()
    {
        //receive data and return
        //return pdu;
    }

}

You could also do it the otherway around that the Receiver class has a reference to the GUI and will inform it when new data arrives. See the Observer Pattern

Andere Tipps

I believe you are getting an error because you have socket, packet, address and pduFactory declared twice -- once in main and once as members of the class. And you really need to decide if you want receivePdu() to be static or not.

You have a couple decisions to make: 1) Should socket, packet, address and pduFactory be local to receivePdu() or members of EspduReceiver? If the answer to this its "local to receivePdu()", then you need to remove the outer declaration for these variables. If the answer is "members of EspduReceiver" then you need to remove the inner declaration, and maybe refer to each using "this.socket" to make the references clear.

2) Intertwined with that decision is if those variables should be local to the method or members of the class is if receivePdu() is static or not.

So I think there are three overall approaches:

A) receivePdu() is a static member which accesses only static and local variables (convert the instance variables to static variables (as @barak says) and remove the local variables.)

B) receivePdu() is a method invoked on an instance of EspduReceiver, so you need to instantiate an instance of EspduReceiver in order to envoke it. "socket" and the other variables should be members, not re-declared in receivePdu()

C) set up receivePdu() as a singleton class, and proceed similarly to "B".

good luck!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top