Questions about using third party components

Hello,

I have the /n Software Red Carpet subscription which includes a number of components for Android. or example their IP*Works product includes TCP/IP client and server, FTP client, SMTP client, and so on. I’ve installed this and was able to reference their .jar file and create an instance of a class as shown below.

            ipworks.Ipport port = new ipworks.Ipport();

		public override void onCreate(Bundle savedInstanceState)
	{
		base.onCreate(savedInstanceState);

		// Set our view from the "main" layout resource
		ContentView = R.layout.main;
	}

What I am trying to understand is how to link up events provided by the Ipport. I tried this…

            void ipConnected(View v)
	{

	}

            port.IpportEventListener.connected = ipConnected;

But I receive the message: (E266) Cannot access underlying field to raise event “port.IpportEventListener”

What is the correct way to link events?

I found a demo for their FTP client component, and they’re handling the events using an event listener class so I anticipate it is something similar for the ipport.

I’m not sure how I would translate this from the original Java to Hydrogene:

                 ftp.addFtpEventListener(new DefaultFtpEventListener(){
				public void PITrail(ipworks.FtpPITrailEvent e)
				{
					if(e.direction == 0) //Client
					{
						text.append("CLIENT: " + e.message + "\r\n");
					}
					else if(e.direction == 1) //Server
					{
						text.append("SERVER: " + e.message + "\r\n");
					}
					else //Info
					{
						text.append("INFO: " + e.message + "\r\n");
					}
					text.setSelection(text.length());
				}
			});

This is just the typical/usual way to handle “events” in Java. Instead of assigning a method reference (or delegate) the “event” is implemented as a method on some interface and you provide a reference to an implementation of that interface. This is called the “listener” and implements one or more methods that the interface contract establishes for that particular listener.

So in your example instead of trying to assign anything to the specific connected method instead assign an implementation of the listener interface.

In Java (and Oxygene) that implementation can be anonymous which is what that example code is doing - it inlines the definition of a new type, which is an anonymous class implementation of the DefaultFtpEventListener interface. The PITrail method of that interface is then implemented in the inlined body of that implementation class.

But in C# anonymous types cannot implement interfaces so you will need to use a named type to provide an implementation (that is unless Hydrogene provides for anonymous interface implementation - I don’t know as I don’t actually use Hydrogene so have never run into this problem).

1 Like

I’ve had a look at the IP*Works documentation and cannot find any IpPort component/bean/class that has a (documented) IpPortEventListener property.

I presume you are working with the Android version but what release of IP*Works are you working with ? 2016 ? Older ?

It is the Android version of the IP*Works 2016 controls.

You’re right, I don’t see any specific documentation for the Java / Netbeans or Android editions. This is what their tech support said:

Blockquote
We don’t have documentation for any of the *EventListener classes specifically, but I can tell you that this is how it works (and there are other demos which should help showcase this):
· All components in Java have two methods called addEventListener() andremoveEventListener(), both of which take a single argument of type “EventListener”.
· The “EventListener” type itself is, in fact, an Interface type. It contains a method signature like “public void (Event e);” for each event the component has (so, for example, “public void dataIn(IpportDataInEvent e);”, etc). So you can have a class implement this interface to handle all of the events, and pass an instance of it to the addEventListener() method.
· There is also a class called “DefaultEventListener”; it implements the “EventListener” interface, but all of the method implementations are empty. So, if you wanted to only handle a handful of all possible events (which is pretty common), you could make a class which extends this default event listener class, and then override the method implementations (I’ll assume you can find out how to do this in Java) for just the events you want to handle, and pass an instance of it to the addEventListener()method.
· You’ll notice that the event methods themselves take a single parameter of type “Event”; this type is just a simple class which holds the event values. So for the DataIn event, for example, it has two members, “byte text”, and “Boolean EOL”, just like the docs show.
Hopefully this gives you a better idea of how events work in Java; I can probably scrounge up some more concrete examples if you need them, just let me know.

It sounds like in Hydrogene (C#) I would need to create a class that implements the specific interface or descend from the DefaultEventListener class and override specific methods. Then call addEventListener to register the class with the Ipport.

Alternatively, it seems as though elements will allow me to add a Java class to the C# project and use the anonymous implementation method shown in their example. This might get me up and running quicker.

you can also just implement the interface and method in the class you’re already in, of course. deep dmg on whether that makes sense, structure wise.

On the latter point, I don’t think you will be able to do that. Your C# code can extend the default listener class but the limitations of C# anonymous classes still prevent you from using it in the same way as Java.

In C# anonymous classes always extend Object - you cannot extend from some other class, and therefore you cannot override existing virtual methods in any concrete class using an anonymous subclass.

In C# you will need to declare a named class that extends the default listener and overrides the required methods. Alternatively, as Marc suggested, you could implement the required listener interface on one of your existing classes.

The key is that the listener is a class that implements the required interface - the default listener class is a convenience for Java developers (and Oxygene, coincidentally) but doesn’t help much in the case of C# due to those limitations of C# anonymous types.

Worth mentioning is that these limitations are baked into the C# language specification; they are not a limitation of the Hydrogene implementation.

Ironically, Oxygene supports these things very well indeed (“ironically” because I suspect people might expect C# to be more similar to/have more equivalence with Java than they would Oxygene). :slight_smile: