Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Kura » Java swing on Kura in OSGI(Java swing on Kura)
Java swing on Kura in OSGI [message #1758442] Tue, 28 March 2017 17:29 Go to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Dave & Folks,

I am trying to display java swing window from an OSGI bundle , deployed to Kura.

I am not finding any exception in Kura. But NO display either.
The Kura thread simply hangs.. as I guess .. as I cant see the Kura log getting populated ...see below...

2017-03-27 23:21:41,148 [pool-25-thread-1] INFO o.s.k.s.p.ManageSensorActions - Showing Image when No one is Around
2017-03-27 23:21:41,416 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Message arrived on topic: $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-03-27 23:21:41,417 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Ignoring feedback message from $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-03-27 23:23:08,


in my code :

Activate method to Display image method flow & then



void displayimage(boolean promiximity)
{


/* display frame directly
JFrame frame = new JFrame();
ImageIcon icon = new ImageIcon("promo.jpg");
JLabel label = new JLabel(icon);
frame.add(label);
frame.setDefaultCloseOperation
(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
*/
JFrame frame = new JFrame("Hello World");
frame.setSize(640,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

}catch(Exception e)
{
s_logger.info("Exception when showing Image when someone is Near"+e);
}

}
.......

}
}
============

I tried to create a standalone java swing application in my Pi.
It is working fine.. in fact the same swing code is working fine.


wondering whats going on... Sad
Re: Java swing on Kura in OSGI [message #1758444 is a reply to message #1758442] Tue, 28 March 2017 18:19 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Also I am seeing the thread is being blocked for other bundles deployed in Kura where this first bundle(with swing GUI code) is deployed...the thread is stuck..

this is also not allowing other bundles to run properly....which were running properly when I did not introduce the swing code in the first bundle...

2017-03-28 23:14:30,631 [pool-24-thread-1] INFO o.s.k.s.t.SI7021_I2C - exception in i2c readingjava.lang.InterruptedException: sleep interrupted
2017-03-28 23:14:30,634 [pool-24-thread-1] ERROR o.s.k.s.t.SI7021_I2C - Cannot publish topic:


Re: Java swing on Kura in OSGI [message #1758452 is a reply to message #1758444] Tue, 28 March 2017 19:25 Go to previous messageGo to next message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

It is helpful to keep all your questions in one thread. I will use this thread to try and assist. First, I am far from a JavaFX expert and had trouble using Frames in the past, but the approach I have used is:

1. In activate, create a panel, something like:
          jpanel = new JPanel();
          jpanel.setSize(400, 400);
          jpanel.setLayout(new GridLayout(3, 1));
    
          headerLabel = new Label();
          headerLabel.setAlignment(Label.CENTER);
          statusLabel = new Label();    
          statusLabel.setAlignment(Label.CENTER);
          statusLabel.setSize(350,100);

          controlPanel = new Panel();
          controlPanel.setLayout(new FlowLayout());

          jpanel.add(headerLabel);
          jpanel.add(controlPanel);
          jpanel.add(statusLabel);
          jpanel.setVisible(true);  


2. Add the Frame:
          controlPanel.add(new DemoFrame());
          controlPanel.setVisible(true);
          jpanel.setVisible(true);


3. Example DemoFrame Class:
public class DemoFrame extends Canvas {
    /** 
     * 
     */
    private static final long serialVersionUID = 3156965697737887068L;
    private static final Logger s_logger = LoggerFactory.getLogger(DemoFrame.class);
    
    public DemoFrame () {
        setBackground (Color.GRAY);
        setSize(300, 300);
     }   
    
    @Override
    public void paint(Graphics g) {
        Graphics2D g2; 
       g2 = (Graphics2D) g;
       g2.drawString ("It is a custom canvas area", 70, 70);
   }   
}


Thanks,
--Dave
Re: Java swing on Kura in OSGI [message #1758491 is a reply to message #1758452] Wed, 29 March 2017 09:07 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
is it required to put the Swing code in Activate method only....
can I not put swing code in another method that is being called from activate method. ?


In my original code I was calling the swing code from the Display method , which itself is being called from activate method, but each Display method is called from a new thread.

regards
Amar

Now do i need to run these code from a new thread ..

regards
Amar
Re: Java swing on Kura in OSGI [message #1758512 is a reply to message #1758491] Wed, 29 March 2017 13:39 Go to previous messageGo to next message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

You can put any code you wish in the activate method, including calls to other methods, but the Activate method must return. If the activate method does not return, the bundle will not be registered in the framework. It is considered a best practice to keep your activate method as small and fast as possible. If you have longer running processing to perform, start a separate thread from the activate method to handle this.

Thanks,
--Dave
Re: Java swing on Kura in OSGI [message #1758573 is a reply to message #1758512] Thu, 30 March 2017 08:35 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
I tried the Code suggested .. but still did not get any display.. Smile
Re: Java swing on Kura in OSGI [message #1758697 is a reply to message #1758573] Fri, 31 March 2017 17:43 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
here is the code I am using..
package org.eclipse.kura.example.hello_osgi;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.eclipse.kura.cloud.CloudClient;
import org.eclipse.kura.cloud.CloudClientListener;
import org.eclipse.kura.cloud.CloudService;
import org.eclipse.kura.configuration.ConfigurableComponent;
import org.eclipse.kura.gpio.GPIOService;
import org.eclipse.kura.gpio.KuraGPIOPin;
import org.eclipse.kura.message.KuraPayload;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.kura.example.hello_osgi.DemoFrame;

public class HelloOsgi implements ConfigurableComponent,CloudClientListener{

//Worker thread

private final ScheduledExecutorService m_worker;
private ScheduledFuture<?> m_handle;

//GPIO service

private GPIOService m_GPIOService; //static modifier removed

//Cloud service
private CloudService m_cloudService;
private CloudClient m_cloudClient;

private Map<String, Object> m_properties;

// publishing properties
// Publishing Property Names
private static final String PUBLISH_RATE_PROP_NAME = "publish.rate";
private static final String PUBLISH_TOPIC_PROP_NAME = "publish.semanticTopic";
private static final String PUBLISH_QOS_PROP_NAME = "publish.qos";
private static final String PUBLISH_RETAIN_PROP_NAME = "publish.retain";

private static final Logger s_logger = LoggerFactory.getLogger(HelloOsgi.class);

private static final String APP_ID = "org.eclipse.kura.example.hello_osgi";


//constructor

public HelloOsgi() {
super();
this.m_worker = Executors.newSingleThreadScheduledExecutor();
}


/*
* protected void activate(ComponentContext componentContext) {

s_logger.info("Bundle " + APP_ID + " has started!");

s_logger.debug(APP_ID + ": This is a debug message.");
//readLED();

}
*/

protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
try{
s_logger.info("Bundle " + APP_ID + " has started with config!");

this.m_properties = properties;
for (String s : properties.keySet()) {
s_logger.info("Activate - " + s + ": " + properties.get(s));
}

// Acquire a Cloud Application Client for this Application
s_logger.info("Getting CloudClient for {}...", APP_ID);
this.m_cloudClient = this.m_cloudService.newCloudClient(APP_ID);
this.m_cloudClient.addCloudClientListener(this);


//doUpdate();

/* Test Swing */

Runnable runnable = new Runnable() {
public void run() {
createAndShow();
}
};

}
catch(Exception e)
{
s_logger.info("activation issue...", e.toString());
}

s_logger.info("Activating Hello osgi... Done.");
}

public void updated(Map<String, Object> properties) {
// TODO Auto-generated method stub
s_logger.info("Updated properties...");
this.m_properties = properties;

for (String s : properties.keySet()) {
s_logger.info("Update - " + s + ": " + properties.get(s));
}


s_logger.info("Updated ExamplePublisher... Done.");
if(properties != null && !properties.isEmpty()) {
Iterator<Entry<String, Object>> it = properties.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object> entry = it.next();
s_logger.info("New property - " + entry.getKey() + " = " +
entry.getValue() + " of type " + entry.getValue().getClass().toString());
}
}


// try to kick off a new job
doUpdate();




}

protected void deactivate(ComponentContext componentContext) {

// shutting down the worker and cleaning up the properties
this.m_worker.shutdown();

// Releasing the CloudApplicationClient
s_logger.info("Releasing CloudApplicationClient for {}...", APP_ID);
this.m_cloudClient.release();

s_logger.debug("Deactivating ExamplePublisher... Done.");

s_logger.info("Bundle " + APP_ID + " has stopped!");

}
protected void setGPIOService(GPIOService gpioService){

this.m_GPIOService = gpioService;
}

protected void unsetGPIOService(GPIOService gpioService) {
this.m_GPIOService = null;
}

//cloud publisher service
public void setCloudService(CloudService cloudService) {
m_cloudService = cloudService;
}
public void unsetCloudService(CloudService cloudService) {
m_cloudService = null;
}


private void doUpdate() {

// cancel a current worker handle if one if active
if (this.m_handle != null) {
this.m_handle.cancel(true);
}
// schedule a new worker based on the properties of the service
int pubrate = (Integer) this.m_properties.get(PUBLISH_RATE_PROP_NAME);
this.m_handle = this.m_worker.scheduleAtFixedRate(new Runnable() {

// @Override
public void run() {
doPublish();
}
}, 0, pubrate, TimeUnit.MINUTES);
}

public void doPublish()
{

// fetch the publishing configuration from the publishing properties
String topic = (String) this.m_properties.get(PUBLISH_TOPIC_PROP_NAME);
Integer qos = (Integer) this.m_properties.get(PUBLISH_QOS_PROP_NAME);
Boolean retain = (Boolean) this.m_properties.get(PUBLISH_RETAIN_PROP_NAME);


// Allocate a new payload
KuraPayload payload = new KuraPayload();

// Timestamp the message
payload.setTimestamp(new Date());

// Add the temperature as a metric to the payload
payload.addMetric("temperature", 27.8);



// Publish the message
try {
s_logger.info("trying to Publish to Topic:", topic, payload);
m_cloudClient.publish(topic, payload,qos, retain);
s_logger.info("Published to {} message: {}", topic, payload);
}
catch (Exception e) {
s_logger.error("Cannot publish topic: "+topic, e);
}


}

@Override
public void onConnectionEstablished() {
// TODO Auto-generated method stub

}

@Override
public void onConnectionLost() {
// TODO Auto-generated method stub

}

@Override
public void onControlMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageConfirmed(int arg0, String arg1) {
// TODO Auto-generated method stub

}

@Override
public void onMessagePublished(int arg0, String arg1) {
// TODO Auto-generated method stub

}

/* test swing method */
static void createAndShow() {
s_logger.info("Entered createAndShow method");
JFrame frame = new JFrame("Hello World");
frame.setSize(640,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
s_logger.info("swing code execued ffrom createAndShow method");
}




}
Re: Java swing on Kura in OSGI [message #1758705 is a reply to message #1758697] Fri, 31 March 2017 18:59 Go to previous messageGo to next message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

I see you are creating a runnable for you Swing app, but I don't think you are starting it. Unless I am missing something.

Thanks,
--Dave
Re: Java swing on Kura in OSGI [message #1758724 is a reply to message #1758705] Sat, 01 April 2017 06:04 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Thank you Dave, for your reply.. I did tthe invocation
SwingUtilities.invokeLater( runnable) and it also shows nothing...
then I tried SwingUtilities.invokeAndwait(runnable) ... also getting no display....

I finally change the code as suggested by you .....

====

package org.eclipse.kura.example.hello_osgi;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import org.eclipse.kura.cloud.CloudClient;
import org.eclipse.kura.cloud.CloudClientListener;
import org.eclipse.kura.cloud.CloudService;
import org.eclipse.kura.configuration.ConfigurableComponent;
import org.eclipse.kura.gpio.GPIOService;
import org.eclipse.kura.gpio.KuraGPIOPin;
import org.eclipse.kura.message.KuraPayload;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.kura.example.hello_osgi.DemoFrame;

public class HelloOsgi implements ConfigurableComponent,CloudClientListener{

//Worker thread

private final ScheduledExecutorService m_worker;
private ScheduledFuture<?> m_handle;

//GPIO service

private GPIOService m_GPIOService; //static modifier removed

//Cloud service
private CloudService m_cloudService;
private CloudClient m_cloudClient;

private Map<String, Object> m_properties;

// publishing properties
// Publishing Property Names
private static final String PUBLISH_RATE_PROP_NAME = "publish.rate";
private static final String PUBLISH_TOPIC_PROP_NAME = "publish.semanticTopic";
private static final String PUBLISH_QOS_PROP_NAME = "publish.qos";
private static final String PUBLISH_RETAIN_PROP_NAME = "publish.retain";

private static final Logger s_logger = LoggerFactory.getLogger(HelloOsgi.class);

private static final String APP_ID = "org.eclipse.kura.example.hello_osgi";


//constructor

public HelloOsgi() {
super();
this.m_worker = Executors.newSingleThreadScheduledExecutor();
}


/*
* protected void activate(ComponentContext componentContext) {

s_logger.info("Bundle " + APP_ID + " has started!");

s_logger.debug(APP_ID + ": This is a debug message.");
//readLED();

}
*/

protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
try{
s_logger.info("Bundle " + APP_ID + " has started with config!");

this.m_properties = properties;
for (String s : properties.keySet()) {
s_logger.info("Activate - " + s + ": " + properties.get(s));
}

// Acquire a Cloud Application Client for this Application
s_logger.info("Getting CloudClient for {}...", APP_ID);
this.m_cloudClient = this.m_cloudService.newCloudClient(APP_ID);
this.m_cloudClient.addCloudClientListener(this);


//doUpdate();

/* Test Swing */
JPanel jpanel = new JPanel();
jpanel.setSize(400, 400);
jpanel.setLayout(new GridLayout(3, 1));

Label headerLabel = new Label();
headerLabel.setAlignment(Label.CENTER);
Label statusLabel = new Label();
statusLabel.setAlignment(Label.CENTER);
statusLabel.setSize(350,100);

Panel controlPanel = new Panel();
controlPanel.setLayout(new FlowLayout());

jpanel.add(headerLabel);
jpanel.add(controlPanel);
jpanel.add(statusLabel);
jpanel.setVisible(true);

controlPanel.add(new DemoFrame());
controlPanel.setVisible(true);
jpanel.setVisible(true);

}
catch(Exception e)
{
s_logger.info("activation issue...", e.toString());
}

s_logger.info("Activating Hello osgi... Done.");
}

public void updated(Map<String, Object> properties) {
// TODO Auto-generated method stub
s_logger.info("Updated properties...");
this.m_properties = properties;

for (String s : properties.keySet()) {
s_logger.info("Update - " + s + ": " + properties.get(s));
}


s_logger.info("Updated ExamplePublisher... Done.");
if(properties != null && !properties.isEmpty()) {
Iterator<Entry<String, Object>> it = properties.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object> entry = it.next();
s_logger.info("New property - " + entry.getKey() + " = " +
entry.getValue() + " of type " + entry.getValue().getClass().toString());
}
}


// try to kick off a new job
doUpdate();




}

protected void deactivate(ComponentContext componentContext) {

// shutting down the worker and cleaning up the properties
this.m_worker.shutdown();

// Releasing the CloudApplicationClient
s_logger.info("Releasing CloudApplicationClient for {}...", APP_ID);
this.m_cloudClient.release();

s_logger.debug("Deactivating ExamplePublisher... Done.");

s_logger.info("Bundle " + APP_ID + " has stopped!");

}
protected void setGPIOService(GPIOService gpioService){

this.m_GPIOService = gpioService;
}

protected void unsetGPIOService(GPIOService gpioService) {
this.m_GPIOService = null;
}

//cloud publisher service
public void setCloudService(CloudService cloudService) {
m_cloudService = cloudService;
}
public void unsetCloudService(CloudService cloudService) {
m_cloudService = null;
}


public void readLED(){

try{
int counter =0; // for max number of times
//get LED pin
KuraGPIOPin led=m_GPIOService.getPinByTerminal(17);
if(!led.isOpen())
led.open();
if(led !=null)
{
s_logger.info("Direction " + led.getDirection());
s_logger.info("Triger " + led.getTrigger());
s_logger.info("Mode " + led.getMode());
s_logger.info("Value " + led.getValue());
led.setValue(false); // start LED as off
}

while(true)
{

s_logger.info("Trying to read & control LED as stated by Amar");

//read LED pin

if(led.getValue()==true) led.setValue(false);

Thread.sleep(2000);
if(led.getValue()==false) led.setValue(true);
// s_logger.info("");
Thread.sleep(2000);
boolean currentstate= led.getValue() ;

s_logger.info("LED state is:"+currentstate);
if(counter>=60)
break;
counter++;
}
}catch(Exception e)
{
s_logger.info("problem in reading led " + e.toString());
}


}


private void doUpdate() {

// cancel a current worker handle if one if active
if (this.m_handle != null) {
this.m_handle.cancel(true);
}
// schedule a new worker based on the properties of the service
int pubrate = (Integer) this.m_properties.get(PUBLISH_RATE_PROP_NAME);
this.m_handle = this.m_worker.scheduleAtFixedRate(new Runnable() {

// @Override
public void run() {
doPublish();
}
}, 0, pubrate, TimeUnit.MINUTES);
}

public void doPublish()
{

// fetch the publishing configuration from the publishing properties
String topic = (String) this.m_properties.get(PUBLISH_TOPIC_PROP_NAME);
Integer qos = (Integer) this.m_properties.get(PUBLISH_QOS_PROP_NAME);
Boolean retain = (Boolean) this.m_properties.get(PUBLISH_RETAIN_PROP_NAME);


// Allocate a new payload
KuraPayload payload = new KuraPayload();

// Timestamp the message
payload.setTimestamp(new Date());

// Add the temperature as a metric to the payload
payload.addMetric("temperature", 27.8);



// Publish the message
try {
s_logger.info("trying to Publish to Topic:", topic, payload);
m_cloudClient.publish(topic, payload,qos, retain);
s_logger.info("Published to {} message: {}", topic, payload);
}
catch (Exception e) {
s_logger.error("Cannot publish topic: "+topic, e);
}


}

@Override
public void onConnectionEstablished() {
// TODO Auto-generated method stub

}

@Override
public void onConnectionLost() {
// TODO Auto-generated method stub

}

@Override
public void onControlMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageConfirmed(int arg0, String arg1) {
// TODO Auto-generated method stub

}

@Override
public void onMessagePublished(int arg0, String arg1) {
// TODO Auto-generated method stub

}

/* test swing method */
static void createAndShow() {
s_logger.info("Entered createAndShow method");
JFrame frame = new JFrame("Hello World");
frame.setSize(640,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
s_logger.info("swing code execued ffrom createAndShow method");
}

}


Not getting any clue... Sad
Re: Java swing on Kura in OSGI [message #1758725 is a reply to message #1758724] Sat, 01 April 2017 06:20 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Also I tried with a separate thread.....as in the below code ..but still no display .....

====

package org.eclipse.kura.example.hello_osgi;

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.Panel;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import org.eclipse.kura.cloud.CloudClient;
import org.eclipse.kura.cloud.CloudClientListener;
import org.eclipse.kura.cloud.CloudService;
import org.eclipse.kura.configuration.ConfigurableComponent;
import org.eclipse.kura.gpio.GPIOService;
import org.eclipse.kura.gpio.KuraGPIOPin;
import org.eclipse.kura.message.KuraPayload;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.eclipse.kura.example.hello_osgi.DemoFrame;

public class HelloOsgi implements ConfigurableComponent,CloudClientListener{

//Worker thread

private final ScheduledExecutorService m_worker;
private ScheduledFuture<?> m_handle;

//GPIO service

private GPIOService m_GPIOService; //static modifier removed

//Cloud service
private CloudService m_cloudService;
private CloudClient m_cloudClient;

private Map<String, Object> m_properties;

// publishing properties
// Publishing Property Names
private static final String PUBLISH_RATE_PROP_NAME = "publish.rate";
private static final String PUBLISH_TOPIC_PROP_NAME = "publish.semanticTopic";
private static final String PUBLISH_QOS_PROP_NAME = "publish.qos";
private static final String PUBLISH_RETAIN_PROP_NAME = "publish.retain";

private static final Logger s_logger = LoggerFactory.getLogger(HelloOsgi.class);

private static final String APP_ID = "org.eclipse.kura.example.hello_osgi";


//constructor

public HelloOsgi() {
super();
this.m_worker = Executors.newSingleThreadScheduledExecutor();
}


/*
* protected void activate(ComponentContext componentContext) {

s_logger.info("Bundle " + APP_ID + " has started!");

s_logger.debug(APP_ID + ": This is a debug message.");
//readLED();

}
*/

protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
try{
s_logger.info("Bundle " + APP_ID + " has started with config!");

this.m_properties = properties;
for (String s : properties.keySet()) {
s_logger.info("Activate - " + s + ": " + properties.get(s));
}

// Acquire a Cloud Application Client for this Application
s_logger.info("Getting CloudClient for {}...", APP_ID);
this.m_cloudClient = this.m_cloudService.newCloudClient(APP_ID);
this.m_cloudClient.addCloudClientListener(this);


//doUpdate();

/* Test Swing */

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {

JPanel jpanel = new JPanel();
jpanel.setSize(400, 400);
jpanel.setLayout(new GridLayout(3, 1));

Label headerLabel = new Label();
headerLabel.setAlignment(Label.CENTER);
Label statusLabel = new Label();
statusLabel.setAlignment(Label.CENTER);
statusLabel.setSize(350,100);

Panel controlPanel = new Panel();
controlPanel.setLayout(new FlowLayout());

jpanel.add(headerLabel);
jpanel.add(controlPanel);
jpanel.add(statusLabel);
jpanel.setVisible(true);

controlPanel.add(new DemoFrame());
controlPanel.setVisible(true);
jpanel.setVisible(true);
}
});

}
catch(Exception e)
{
s_logger.info("activation issue...", e.toString());
}

s_logger.info("Activating Hello osgi... Done.");
}

public void updated(Map<String, Object> properties) {
// TODO Auto-generated method stub
s_logger.info("Updated properties...");
this.m_properties = properties;

for (String s : properties.keySet()) {
s_logger.info("Update - " + s + ": " + properties.get(s));
}


s_logger.info("Updated ExamplePublisher... Done.");
if(properties != null && !properties.isEmpty()) {
Iterator<Entry<String, Object>> it = properties.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object> entry = it.next();
s_logger.info("New property - " + entry.getKey() + " = " +
entry.getValue() + " of type " + entry.getValue().getClass().toString());
}
}


// try to kick off a new job
doUpdate();




}

protected void deactivate(ComponentContext componentContext) {

// shutting down the worker and cleaning up the properties
this.m_worker.shutdown();

// Releasing the CloudApplicationClient
s_logger.info("Releasing CloudApplicationClient for {}...", APP_ID);
this.m_cloudClient.release();

s_logger.debug("Deactivating ExamplePublisher... Done.");

s_logger.info("Bundle " + APP_ID + " has stopped!");

}
protected void setGPIOService(GPIOService gpioService){

this.m_GPIOService = gpioService;
}

protected void unsetGPIOService(GPIOService gpioService) {
this.m_GPIOService = null;
}

//cloud publisher service
public void setCloudService(CloudService cloudService) {
m_cloudService = cloudService;
}
public void unsetCloudService(CloudService cloudService) {
m_cloudService = null;
}


public void readLED(){

try{
int counter =0; // for max number of times
//get LED pin
KuraGPIOPin led=m_GPIOService.getPinByTerminal(17);
if(!led.isOpen())
led.open();
if(led !=null)
{
s_logger.info("Direction " + led.getDirection());
s_logger.info("Triger " + led.getTrigger());
s_logger.info("Mode " + led.getMode());
s_logger.info("Value " + led.getValue());
led.setValue(false); // start LED as off
}

while(true)
{

s_logger.info("Trying to read & control LED as stated by Amar");

//read LED pin

if(led.getValue()==true) led.setValue(false);

Thread.sleep(2000);
if(led.getValue()==false) led.setValue(true);
// s_logger.info("");
Thread.sleep(2000);
boolean currentstate= led.getValue() ;

s_logger.info("LED state is:"+currentstate);
if(counter>=60)
break;
counter++;
}
}catch(Exception e)
{
s_logger.info("problem in reading led " + e.toString());
}


}


private void doUpdate() {

// cancel a current worker handle if one if active
if (this.m_handle != null) {
this.m_handle.cancel(true);
}
// schedule a new worker based on the properties of the service
int pubrate = (Integer) this.m_properties.get(PUBLISH_RATE_PROP_NAME);
this.m_handle = this.m_worker.scheduleAtFixedRate(new Runnable() {

// @Override
public void run() {
doPublish();
}
}, 0, pubrate, TimeUnit.MINUTES);
}

public void doPublish()
{

// fetch the publishing configuration from the publishing properties
String topic = (String) this.m_properties.get(PUBLISH_TOPIC_PROP_NAME);
Integer qos = (Integer) this.m_properties.get(PUBLISH_QOS_PROP_NAME);
Boolean retain = (Boolean) this.m_properties.get(PUBLISH_RETAIN_PROP_NAME);


// Allocate a new payload
KuraPayload payload = new KuraPayload();

// Timestamp the message
payload.setTimestamp(new Date());

// Add the temperature as a metric to the payload
payload.addMetric("temperature", 27.8);



// Publish the message
try {
s_logger.info("trying to Publish to Topic:", topic, payload);
m_cloudClient.publish(topic, payload,qos, retain);
s_logger.info("Published to {} message: {}", topic, payload);
}
catch (Exception e) {
s_logger.error("Cannot publish topic: "+topic, e);
}


}

@Override
public void onConnectionEstablished() {
// TODO Auto-generated method stub

}

@Override
public void onConnectionLost() {
// TODO Auto-generated method stub

}

@Override
public void onControlMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageArrived(String arg0, String arg1, KuraPayload arg2, int arg3, boolean arg4) {
// TODO Auto-generated method stub

}

@Override
public void onMessageConfirmed(int arg0, String arg1) {
// TODO Auto-generated method stub

}

@Override
public void onMessagePublished(int arg0, String arg1) {
// TODO Auto-generated method stub

}



}

Re: Java swing on Kura in OSGI [message #1758726 is a reply to message #1758725] Sat, 01 April 2017 06:27 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
One pattern I am finding is that it seems Activate method is not returning ....as I never see the is line in my Kura.log file

protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
try{
s_logger.info("Bundle " + APP_ID + " has started with config!");

this.m_properties = properties;
for (String s : properties.keySet()) {
s_logger.info("Activate - " + s + ": " + properties.get(s));
}

// Acquire a Cloud Application Client for this Application
s_logger.info("Getting CloudClient for {}...", APP_ID);
this.m_cloudClient = this.m_cloudService.newCloudClient(APP_ID);
this.m_cloudClient.addCloudClientListener(this);


//doUpdate();

/* Test Swing */

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {

JPanel jpanel = new JPanel();
jpanel.setSize(400, 400);
jpanel.setLayout(new GridLayout(3, 1));

Label headerLabel = new Label();
headerLabel.setAlignment(Label.CENTER);
Label statusLabel = new Label();
statusLabel.setAlignment(Label.CENTER);
statusLabel.setSize(350,100);

Panel controlPanel = new Panel();
controlPanel.setLayout(new FlowLayout());

jpanel.add(headerLabel);
jpanel.add(controlPanel);
jpanel.add(statusLabel);
jpanel.setVisible(true);

controlPanel.add(new DemoFrame());
controlPanel.setVisible(true);
jpanel.setVisible(true);
}
});

}
catch(Exception e)
{
s_logger.info("activation issue...", e.toString());
}

s_logger.info("Activating Hello osgi... Done.");
// this line is not executing
}

Kura.log :

....
017-04-01 11:16:43,767 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.semanticTopic: data
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - kura.service.pid: org.eclipse.kura.example.hello_osgi.HelloOsgi
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - param2.Salary: 15.5
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.rate: 1
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - service.pid: org.eclipse.kura.example.hello_osgi.HelloOsgi
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - component.id: 52
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - param1.Name: Amarendra
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.qos: 0
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.retain: false
2017-04-01 11:16:43,770 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Getting CloudClient for org.eclipse.kura.example.hello_osgi...
2017-04-01 11:16:43,886 [Component Resolve Thread (Bundle 7)] INFO o.e.k.c.d.DataServiceImpl - Storing message on topic :$EDC/#account-name/#client-id/MQTT/APPS, priority: 0
2017-04-01 11:16:43,892 [Component Resolve Thread (Bundle 7)] INFO o.e.k.c.d.DataServiceImpl - Stored message on topic :$EDC/#account-name/#client-id/MQTT/APPS, priority: 0
2017-04-01 11:16:43,897 [DataServiceImpl:Submit] INFO o.e.k.c.d.t.m.MqttDataTransport - Publishing message on topic: $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS with QoS: 0
2017-04-01 11:16:44,203 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Message arrived on topic: $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-04-01 11:16:44,204 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Ignoring feedback message from $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-04-01 11:19:26,497 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask started.
2017-04-01 11:19:26,501 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask: Check store...
2017-04-01 11:19:26,507 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask: Delete confirmed messages...
2017-04-01 11:19:26,516 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask ended.
Re: Java swing on Kura in OSGI [message #1758727 is a reply to message #1758725] Sat, 01 April 2017 06:28 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
One pattern I am finding is that it seems Activate method is not returning ....as I never see the is line in my Kura.log file

protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
try{
s_logger.info("Bundle " + APP_ID + " has started with config!");

this.m_properties = properties;
for (String s : properties.keySet()) {
s_logger.info("Activate - " + s + ": " + properties.get(s));
}

// Acquire a Cloud Application Client for this Application
s_logger.info("Getting CloudClient for {}...", APP_ID);
this.m_cloudClient = this.m_cloudService.newCloudClient(APP_ID);
this.m_cloudClient.addCloudClientListener(this);


//doUpdate();

/* Test Swing */

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {

JPanel jpanel = new JPanel();
jpanel.setSize(400, 400);
jpanel.setLayout(new GridLayout(3, 1));

Label headerLabel = new Label();
headerLabel.setAlignment(Label.CENTER);
Label statusLabel = new Label();
statusLabel.setAlignment(Label.CENTER);
statusLabel.setSize(350,100);

Panel controlPanel = new Panel();
controlPanel.setLayout(new FlowLayout());

jpanel.add(headerLabel);
jpanel.add(controlPanel);
jpanel.add(statusLabel);
jpanel.setVisible(true);

controlPanel.add(new DemoFrame());
controlPanel.setVisible(true);
jpanel.setVisible(true);
}
});

}
catch(Exception e)
{
s_logger.info("activation issue...", e.toString());
}

s_logger.info("Activating Hello osgi... Done.");
// this line is not executing
}

Kura.log :

....
017-04-01 11:16:43,767 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.semanticTopic: data
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - kura.service.pid: org.eclipse.kura.example.hello_osgi.HelloOsgi
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - param2.Salary: 15.5
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.rate: 1
2017-04-01 11:16:43,768 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - service.pid: org.eclipse.kura.example.hello_osgi.HelloOsgi
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - component.id: 52
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - param1.Name: Amarendra
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.qos: 0
2017-04-01 11:16:43,769 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Activate - publish.retain: false
2017-04-01 11:16:43,770 [Component Resolve Thread (Bundle 7)] INFO o.e.k.e.h.HelloOsgi - Getting CloudClient for org.eclipse.kura.example.hello_osgi...
2017-04-01 11:16:43,886 [Component Resolve Thread (Bundle 7)] INFO o.e.k.c.d.DataServiceImpl - Storing message on topic :$EDC/#account-name/#client-id/MQTT/APPS, priority: 0
2017-04-01 11:16:43,892 [Component Resolve Thread (Bundle 7)] INFO o.e.k.c.d.DataServiceImpl - Stored message on topic :$EDC/#account-name/#client-id/MQTT/APPS, priority: 0
2017-04-01 11:16:43,897 [DataServiceImpl:Submit] INFO o.e.k.c.d.t.m.MqttDataTransport - Publishing message on topic: $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS with QoS: 0
2017-04-01 11:16:44,203 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Message arrived on topic: $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-04-01 11:16:44,204 [MQTT Call: B8:27:EB:52:3D:F6] INFO o.e.k.c.c.CloudServiceImpl - Ignoring feedback message from $EDC/retailIOT/B8:27:EB:52:3D:F6/MQTT/APPS
2017-04-01 11:19:26,497 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask started.
2017-04-01 11:19:26,501 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask: Check store...
2017-04-01 11:19:26,507 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask: Delete confirmed messages...
2017-04-01 11:19:26,516 [HouseKeeperTask] INFO o.e.k.c.d.s.HouseKeeperTask - HouseKeeperTask ended.
Re: Java swing on Kura in OSGI [message #1758742 is a reply to message #1758727] Sat, 01 April 2017 15:00 Go to previous messageGo to next message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

This is not the same code you posted previously. I am not an expert on Swing, but I don't think you can have SwingUtilities.invokeLate in the activate class. Anything you want to start from the activate class should be put in a separate thread. Please see this example [1] for how to properly start a long running thread from the activate method.

[1] https://github.com/eclipse/kura/blob/develop/kura/examples/org.eclipse.kura.demo.heater/src/main/java/org/eclipse/kura/demo/heater/Heater.java

Thanks,
--Dave
Re: Java swing on Kura in OSGI [message #1758776 is a reply to message #1758742] Sun, 02 April 2017 17:30 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Yes I follow ed this. and Created a separate thread to invoke swing .
Infact I did a small standalone app using the same code. This is working fine as stand alone java application.

So seems some display problem with KURA.

My standalone code: -------

package org.superus.kura.sensors.pir;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TestThread {

public static void main(String[] args) {
// TODO Auto-generated method stub
TestThread t = new TestThread();
t.createAndShow();

}


public void createAndShow() {
System.out.println("Entered createAndShow method");


/* Test Swing

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {

JPanel jpanel = new JPanel();
jpanel.setSize(400, 400);
jpanel.setLayout(new GridLayout(3, 1));

Label headerLabel = new Label();
headerLabel.setAlignment(Label.CENTER);
Label statusLabel = new Label();
statusLabel.setAlignment(Label.CENTER);
statusLabel.setSize(350,100);

Panel controlPanel = new Panel();
controlPanel.setLayout(new FlowLayout());

jpanel.add(headerLabel);
jpanel.add(controlPanel);
jpanel.add(statusLabel);
jpanel.setVisible(true);

controlPanel.add(new DemoFrame());
controlPanel.setVisible(true);
jpanel.setVisible(true);

}
});
*/

//option-2

Thread dummyappThread = new Thread() {

public void run() {
try {

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
System.out.println("inside thred run code...");
JFrame frame = new JFrame("Hello World");
frame.setSize(640,480);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});

}
catch (Exception e) {
//s_logger1.info("exception thred run code..."+e);
}

}
};
dummyappThread.start();
}


}

---------

here is the kura start up file where I have put EXPORT DISPLAY -

start_kura_background.sh


/////

#!/bin/sh

# Kura should be installed to the /opt/eclipse directory.
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/opt/jvm/bin:/usr/java/bin:$PATH
export MALLOC_ARENA_MAX=1

#setting Display to X11

#if ! xset q &>/dev/null; then
# echo "Starting X Server..."
# su -s /bin/bash -c xinit root& export DISPLAY=:0.0
# echo "X Server started !"
#else
# echo "X Server already running, DISPLAY variable setted"
#fi

# Direct export display instead of script
export DISPLAY=localhost:0.0

DIR=$(cd $(dirname $0)/..; pwd)
cd $DIR

# set up the configuration area
mkdir -p /tmp/.kura/configuration
cp ${DIR}/kura/config.ini /tmp/.kura/configuration/

KURA_RUNNING=`ps ax | grep java | grep "org.eclipse.osgi"`

if [ -z "$KURA_RUNNING" ] ; then
nohup java -Xms256m -Xmx256m -XX:MaxPermSize=64m \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/kura-heapdump.hprof \
-XX:ErrorFile=/var/log/kura-error.log \
-Dkura.os.version=raspbian \
-Dkura.arch=armv6_hf \
-Dtarget.device=raspberry-pi-bplus \
-Declipse.ignoreApp=true \
-Dkura.home=${DIR}/kura \
-Dkura.configuration=file:${DIR}/kura/kura.properties \
-Dkura.custom.configuration=file:${DIR}/kura/kura_custom.properties \
-Dkura.data.dir=${DIR}/data \
-Ddpa.configuration=${DIR}/kura/dpa.properties \
-Dlog4j.configuration=file:${DIR}/kura/log4j.properties \
-Djava.security.policy=${DIR}/kura/jdk.dio.policy \
-Djdk.dio.registry=${DIR}/kura/jdk.dio.properties \
-Djdk.tls.trustNameService=true \
-jar ${DIR}/plugins/org.eclipse.osgi_3.8.1.v20120830-144521.jar \
-configuration /tmp/.kura/configuration \
-console 5002 \
-consoleLog >> /var/log/kura-console.log 2>> /var/log/kura-console.log &

#Save the PID
KURA_PID=$!
echo "Kura Started (pid="$KURA_PID") ..." >> /var/log/kura-console.log
echo $KURA_PID > /var/run/kura.pid
else
echo "Failed to start Kura. It is already running ..." >> /var/log/kura-console.log
fi

////////


is there anything wrong in these ,, please help me on this.

regards
Amar
Re: Java swing on Kura in OSGI [message #1758959 is a reply to message #1758776] Tue, 04 April 2017 19:33 Go to previous messageGo to next message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

Would it be possible to post your code in Github or supply the complete project as a Zip? I am having a hard time following the code snippets you are providing.

Thanks,
--Dave
Re: Java swing on Kura in OSGI [message #1758989 is a reply to message #1758959] Wed, 05 April 2017 05:44 Go to previous messageGo to next message
Amarendra Sahoo is currently offline Amarendra SahooFriend
Messages: 22
Registered: November 2016
Junior Member
Thanks Dave,

here are the files...

please let me know if you can access the git files...

https://github.com/Amar82/retail-iot.github.io/tree/master/org.eclipse.kura.example.hello_osgi

regrads
Amar
Re: Java swing on Kura in OSGI [message #1759605 is a reply to message #1758989] Thu, 13 April 2017 18:41 Go to previous message
David Woodard is currently offline David WoodardFriend
Messages: 420
Registered: July 2014
Senior Member
Hello,

I would recommend starting with something simpler. I have posted a very simple example here [1]. This code was copied from here [2]. Please note, the second link has important information about running the Swing example in OSX. By following [2], I was able to display the simple panel with the emulator in OSX.

[1] https://github.com/dwoodard1/kura_examples/tree/master/org.dwoodard.kura.example.swing
[2] https://maxrohde.com/2010/06/06/slow-startup-for-swing-applications-in-eclipse-equinox/

Thanks,
--Dave
Previous Topic:Problem installing Kura 1.2.1
Next Topic:Raspberry pi zero w
Goto Forum:
  


Current Time: Tue Apr 16 13:38:13 GMT 2024

Powered by FUDForum. Page generated in 0.10852 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top