How to set default value of UITypeEditor - uitypeeditor

I have this property of a custom object to be displayed in a PropertyGrid:
[DisplayName("Dirección IP Local")]
[Editor(typeof(Configuracion.Editors.IPAddressEditor), typeof(UITypeEditor))]
[Description("Dirección IP del computador en el cual está conectado el dispositivo.")]
public IPAddress IPLocal { get; set; }
In constructor of the same class I have:
this.IPLocal = Common.Helper.ProgramInfo.GetLocalIPAddresses().FirstOrDefault();
The IPAddressEditor is this:
public class IPAddressEditor : UITypeEditor
{
private IWindowsFormsEditorService _editorService;
private IpAddressInput _ipAddressInput;
private bool _escKeyPressed;
public IPAddressEditor()
{
_ipAddressInput = new IpAddressInput();
_ipAddressInput.Width = 150;
_ipAddressInput.BackgroundStyle.BorderWidth = -1;
_ipAddressInput.ButtonClear.Visible = true;
_ipAddressInput.ValueChanged += _ipAddressInput_ValueChanged;
_ipAddressInput.PreviewKeyDown += _ipAddressInput_PreviewKeyDown;
}
void _ipAddressInput_PreviewKeyDown(object sender, System.Windows.Forms.PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Escape)
_escKeyPressed = true;
}
void _ipAddressInput_ValueChanged(object sender, EventArgs e)
{
if (_editorService != null)
_editorService.CloseDropDown();
}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (provider != null)
{
_editorService =
provider.GetService(
typeof(IWindowsFormsEditorService))
as IWindowsFormsEditorService;
}
if (_editorService != null)
{
_escKeyPressed = false;
_editorService.DropDownControl(_ipAddressInput);
if (!_escKeyPressed)
{
IPAddress ip = IPAddress.None;
if (IPAddress.TryParse(_ipAddressInput.Value, out ip))
return ip;
}
}
return value;
}
}
The problem is that the control inside the editor (in this case _ipAddressInput) is not initialized with the value I assigned in object constructor.
This is obvious because in type editor constructor I am creating a new instance of IpAddressInput, so the question is: what is the best way to initialize it?
I was thinking about creating a public setter for that variable and calling in constructor of the custom object using a TypeDescriptor, but I think this is tricky,
Is there a better solution?
Regards
Jaime

Finally, I have found the solution.
I just added
_ipAddressInput.Text = value.ToString();
before the call to
_editorService.DropDownControl(_ipAddressInput);
I have thought about it before but I underestimate it because I was wondering what will happen when updating the property using the editor and whether it will keep the modified value.It was no problem with that and the editor worked like a charm.

Related

How to make clone of static variables of static class in c#

I am working on different approaches of cloning of an objects in c# but currently I stuck with the simple one. I have a static class with static variables & I want to make an exact copy of one of my static variable.I have sketched my code structure below:
public static class RULE_SET
{
public static bool IsdataValid;
public static GCBRequest GCBData;
public static T Clone<T>(this T source)
{
try
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException("The type must be serializable.", "source");
}
if (Object.ReferenceEquals(source, null))
{
return default(T);
}
IFormatter formatter = new BinaryFormatter();
Stream stream = new MemoryStream();
using (stream)
{
formatter.Serialize(stream, source);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
catch (Exception ee) { return default(T); }
}
}
[XmlRoot(ElementName = "GCBRequest")]
public class GCBRequest
{
[XmlElement(ElementName = "PID")]
public string PID { get; set; }
[XmlElement(ElementName = "AID")]
public string AID { get; set; }
[XmlElement(ElementName = "CID")]
public string CID { get; set; }
}
//code to load the RULE_SET
string strJsonRuleset = "{\r\n \"GCdBINRequest\": {\r\n\"PID\": \"(?s).*#M#20\",\r\n\"AID\": \"(?s).*#O#10\",\r\n\"CID\": \"(?s).*#O#25\"\r\n }\r\n}";
public class RULE_SET_LOCAL
{
public static GCBRequest GCBData;
}
//from other method
RULE_SET_LOCAL objParentRuleSet = new RULE_SET_LOCAL();
objParentRuleSet = JsonConvert.DeserializeObject<RULE_SET_LOCAL>(strJsonRuleset);
RULE_SET.GCBData = objParentRuleSet.GCBData;
//Main Method from which I have to create a clone object
Object objRuleset;
objRuleset = RULE_SET.GCBData.Clone();
if(objRuleset == null)
{
** stuck here**
I don't know why Everytime I got the null object ?
}
// but I have use
objRuleset = RULE_SET.GCBData;
if(objRuleset != null)
{
** Successfully reached **
//But I can't do any operation on this object as it will effect the original one.
}
Guys, Do you have any solution/Suggestion ?
Please help me to understand this , any help will be appreciated.
Thanks.
After searching a lot I got this method :
public static T Clone<T>(this T source)
{
var serialized = JsonConvert.SerializeObject(source);
return JsonConvert.DeserializeObject<T>(serialized);
}
& now I am able to get the clone by calling
object objRuleset = RULE_SET.Clone<GCBRequest>(RULE_SET.GCBData);

AltBeacon api return empty collection while ranging beacons

I am trying to range beacons and I am doing exactly what it is written here:
http://altbeacon.github.io/android-beacon-library/samples.html
didRangeBeaconsInRegion method is firing but always with empty collection.
I have installed "locate" by altbeacon and it located 3 beacons.
this is my code: am I missing something?
public class BeaconSingletone implements BeaconConsumer {
private static BeaconSingletone instance;
private final org.altbeacon.beacon.BeaconManager beaconManager2;
private ArrayList<BeaconThin> listNearBeacons = new ArrayList<>();
BeaconRegion region = new BeaconRegion("ranged region",
UUID.fromString("B9407F30-F5F8-466E-AFF9-25556B57FE6D"), null, null);
private List<EventInterface> listeners = new ArrayList<EventInterface>();
private BeaconSingletone()
{
beaconManager2 = org.altbeacon.beacon.BeaconManager.getInstanceForApplication(ar_activity.get());
// To detect proprietary beacons, you must add a line like below corresponding to your beacon
// type. Do a web search for "setBeaconLayout" to get the proper expression.
beaconManager2.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
beaconManager2.bind(this);
public static BeaconSingletone getInstance() {
if(instance == null) {
instance = new BeaconSingletone();
}
return instance;
}
private void showNotification(Region region, final List<Beacon> list) {
listNearBeacons.clear();
listNearBeacons.add(new BeaconThin(3514,7580,-1));
for (Iterator<EventInterface> i = listeners.iterator(); i.hasNext(); ) {
EventInterface item = i.next();
//item.NewBeaconFound(list.get(0).getMajor(),list.get(0).getMinor(),Utils.computeAccuracy(list.get(0)));
item.NewBeaconsFound(listNearBeacons);
}
return;
}
#Override
public void onBeaconServiceConnect() {
beaconManager2.addRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<org.altbeacon.beacon.Beacon> beacons, org.altbeacon.beacon.Region region) {
if (beacons.size() > 0) {
Log.i("BeaconManager", "The first beacon I see is about "+beacons.iterator().next().getDistance()+" meters away.");
}
}
});
try {
beaconManager2.startRangingBeaconsInRegion(new org.altbeacon.beacon.Region("mybeacons", null, null, null));
} catch (RemoteException e) { }{
}
}
#Override
public Context getApplicationContext() {
return ar_activity.get();
}
#Override
public void unbindService(ServiceConnection serviceConnection) {
ar_activity.get().unbindService(serviceConnection);
}
#Override
public boolean bindService(Intent intent, ServiceConnection serviceConnection, int i) {
return ar_activity.get().bindService(intent, serviceConnection, i);
}
}
You need to add a beacon layout for the beacon type you are using (iBeacon?). Replace this line:
beaconManager2.getBeaconParsers().add(new BeaconParser().
setBeaconLayout("m:2-3=beac,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));
With the proper layout from here:
https://beaconlayout.wordpress.com

Getter in an interface with default method JSF

I have an interface with the following default method:
default Integer getCurrentYear() {return DateUtil.getYear();}
I also have a controller that implements this interface, but it does not overwrite the method.
public class NotifyController implements INotifyController
I'm trying to access this method from my xhtml like this:
#{notifyController.currentYear}
However when I open the screen the following error occurs:
The class 'br.com.viasoft.controller.notify.notifyController' does not have the property 'anoAtual'
If I access this method from an instance of my controller, it returns the right value, however when I try to access it from my xhtml as a "property" it occurs this error.
Is there a way to access this interface property from a reference from my controller without having to implement the method?
This may be considered as a bug, or one might argue it is a decision to not support default methods as properties.
See in JDK8 java.beans.Introspector.getPublicDeclaredMethods(Class<?>)
or in JDK13 com.sun.beans.introspect.MethodInfo.get(Class<?>)
at line if (!method.getDeclaringClass().equals(clz))
And only the super class (recursively upto Object, but not the interfaces) are added, see java.beans.Introspector.Introspector(Class<?>, Class<?>, int) when setting superBeanInfo.
Solutions:
Use EL method call syntax (i.e. not property access): #{notifyController.getCurrentYear()} in your case.
Downside: You have to change the JSF code and must consider for each use if it may be a default method. Also refactoring forces changes that are not recognized by the compiler, only during runtime.
Create an EL-Resolver to generically support default methods. But this should use good internal caching like the standard java.beans.Introspector to not slow down the EL parsing.
See "Property not found on type" when using interface default methods in JSP EL for a basic example (without caching).
If only a few classes/interfaces are affected simply create small BeanInfo classes.
The code example below shows this (basing on your example).
Downside: A separate class must be created for each class (that is used in JSF/EL) implementing such an interface.
See also: Default method in interface in Java 8 and Bean Info Introspector
=> static getBeanInfo() in the interface with default methods
=> simple+short BeanInfo class for each class extending the interface
interface INotifyController {
default Integer getCurrentYear() { ... }
default boolean isAHappyYear() { ... }
default void setSomething(String param) { ... }
/** Support for JSF-EL/Beans to get default methods. */
static java.beans.BeanInfo[] getBeanInfo() {
try {
java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(INotifyController.class);
if (info != null) return new java.beans.BeanInfo[] { info };
} catch (java.beans.IntrospectionException e) {
//nothing to do
}
return null;
}
}
public class NotifyController implements INotifyController {
// your class implementation
...
}
// must be a public class and thus in its own file
public class NotifyControllerBeanInfo extends java.beans.SimpleBeanInfo {
#Override
public java.beans.BeanInfo[] getAdditionalBeanInfo() {
return INotifyController.getBeanInfo();
}
}
I found it will be fixed in Jakarta EE 10.
https://github.com/eclipse-ee4j/el-ri/issues/43
Before Jakarta EE 10 you can use custom EL Resolver.
package ru.example.el;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import java.beans.*;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class DefaultMethodELResolver extends ELResolver {
private static final Map<Class<?>, BeanProperties> properties = new ConcurrentHashMap<>();
#Override
public Object getValue(ELContext context, Object base, Object property) {
if (base == null || property == null) {
return null;
}
BeanProperty beanProperty = getBeanProperty(base, property);
if (beanProperty != null) {
Method method = beanProperty.getReadMethod();
if (method == null) {
throw new ELException(String.format("Read method for property '%s' not found", property));
}
Object value;
try {
value = method.invoke(base);
context.setPropertyResolved(base, property);
} catch (Exception e) {
throw new ELException(String.format("Read error for property '%s' in class '%s'", property, base.getClass()), e);
}
return value;
}
return null;
}
#Override
public Class<?> getType(ELContext context, Object base, Object property) {
if (base == null || property == null) {
return null;
}
BeanProperty beanProperty = getBeanProperty(base, property);
if (beanProperty != null) {
context.setPropertyResolved(true);
return beanProperty.getPropertyType();
}
return null;
}
#Override
public void setValue(ELContext context, Object base, Object property, Object value) {
if (base == null || property == null) {
return;
}
BeanProperty beanProperty = getBeanProperty(base, property);
if (beanProperty != null) {
Method method = beanProperty.getWriteMethod();
if (method == null) {
throw new ELException(String.format("Write method for property '%s' not found", property));
}
try {
method.invoke(base, value);
context.setPropertyResolved(base, property);
} catch (Exception e) {
throw new ELException(String.format("Write error for property '%s' in class '%s'", property, base.getClass()), e);
}
}
}
#Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
if (base == null || property == null) {
return false;
}
BeanProperty beanProperty = getBeanProperty(base, property);
if (beanProperty != null) {
context.setPropertyResolved(true);
return beanProperty.isReadOnly();
}
return false;
}
#Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
#Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return Object.class;
}
private BeanProperty getBeanProperty(Object base, Object property) {
return properties.computeIfAbsent(base.getClass(), BeanProperties::new)
.getBeanProperty(property);
}
private static final class BeanProperties {
private final Map<String, BeanProperty> propertyByName = new HashMap<>();
public BeanProperties(Class<?> cls) {
try {
scanInterfaces(cls);
} catch (IntrospectionException e) {
throw new ELException(e);
}
}
private void scanInterfaces(Class<?> cls) throws IntrospectionException {
for (Class<?> ifc : cls.getInterfaces()) {
processInterface(ifc);
}
Class<?> superclass = cls.getSuperclass();
if (superclass != null) {
scanInterfaces(superclass);
}
}
private void processInterface(Class<?> ifc) throws IntrospectionException {
BeanInfo info = Introspector.getBeanInfo(ifc);
for (PropertyDescriptor propertyDescriptor : info.getPropertyDescriptors()) {
String propertyName = propertyDescriptor.getName();
BeanProperty beanProperty = propertyByName
.computeIfAbsent(propertyName, key -> new BeanProperty(propertyDescriptor.getPropertyType()));
if (beanProperty.getReadMethod() == null && propertyDescriptor.getReadMethod() != null) {
beanProperty.setReadMethod(propertyDescriptor.getReadMethod());
}
if (beanProperty.getWriteMethod() == null && propertyDescriptor.getWriteMethod() != null) {
beanProperty.setWriteMethod(propertyDescriptor.getWriteMethod());
}
}
for (Class<?> parentIfc : ifc.getInterfaces()) {
processInterface(parentIfc);
}
}
public BeanProperty getBeanProperty(Object property) {
return propertyByName.get(property.toString());
}
}
private static final class BeanProperty {
private final Class<?> propertyType;
private Method readMethod;
private Method writeMethod;
public BeanProperty(Class<?> propertyType) {
this.propertyType = propertyType;
}
public Class<?> getPropertyType() {
return propertyType;
}
public boolean isReadOnly() {
return getWriteMethod() == null;
}
public Method getReadMethod() {
return readMethod;
}
public void setReadMethod(Method readMethod) {
this.readMethod = readMethod;
}
public Method getWriteMethod() {
return writeMethod;
}
public void setWriteMethod(Method writeMethod) {
this.writeMethod = writeMethod;
}
}
}
You should register EL Resolver in faces-config.xml.
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.3" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_3.xsd">
<name>el_resolver</name>
<application>
<el-resolver>ru.example.el.DefaultMethodELResolver</el-resolver>
</application>
</faces-config>
since this bug is related to JDK, you'll have to create a delegate method in the class that needs the property.

BlackBerry - cancel a thread executed in another class to refresh location

How can I cancel a thread from another class fetching/refreshing location. I am able to cancel a thread from within the same class. But I am unable to do this across classes. Declaring the GPSThread static did not help. Can anyone please guide?
Class1:
public class GPSListener {
/* Other instantiation code */
Dialog busyDialog1 = new Dialog("Refreshing Location...",
new String [] { "Cancel" },
new int [] { Dialog.CANCEL},
Dialog.CANCEL,
Bitmap.getPredefinedBitmap(Bitmap.HOURGLASS))
{
public void fieldChanged(Field field1, int context1)
{
GPSHandler.requestStop();
busyDialog1.cancel();
}
};
public String refreshCoordinates() {
String test = "nothing";
if (GPSHandler.isStopRequested())
{
GPSHandler.stopRequested = false;
return null;
}
GPSHandler.getInstance().setListener(this);
GPSHandler.getInstance().requestLocationUpdates();
if (GPSHandler.isStopRequested())
{
GPSHandler.stopRequested = false;
return null;
}
busyDialog1.setEscapeEnabled(false);
busyDialog1.show();
return test;
}
public void onLocationReceived(Coordinates location) {
lblLatitude.setText(Double.toString(location.getLatitude()));
lblLongitude.setText(Double.toString(location.getLongitude()));
busyDialog1.cancel();
}
}
Class 2:
public class GPSHandler {
private GPSThread _gpsThread;
private Coordinates _location;
private boolean _gotLocation;
private GPSListener _listener;
/** this class will be a Singleton, as the device only has one GPS system */
private static GPSHandler _instance;
/** #return the Singleton instance of the GPSHandler */
public static GPSHandler getInstance() {
if (_instance == null) {
_instance = new GPSHandler();
}
return _instance;
}
public static boolean stopRequested = false;
public synchronized static void requestStop() {
stopRequested = true;
}
public synchronized static boolean isStopRequested() {
return stopRequested;
}
/** not publicly accessible ... use getInstance() */
private GPSHandler() {
}
/** call this to trigger a new location fix */
public void requestLocationUpdates() {
if (_gpsThread == null || !_gpsThread.isAlive()) {
_gpsThread = new GPSThread();
_gpsThread.start();
}
}
public void setListener(GPSListener listener) {
// only supports one listener this way
_listener = listener;
}
private void setLocation(final Coordinates value) {
_location = value;
if (value.getLatitude() != 0.0 || value.getLongitude() != 0.0) {
_gotLocation = true;
if (_listener != null) {
// this assumes listeners are UI listeners, and want callbacks on the UI thread:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
_listener.onLocationReceived(value);
}
});
}
}
}
private class GPSThread extends Thread {
private void getLocationFromGoogle() {
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
writeDataGoogleMaps(outputStream2, cellID, lac);
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
final int code = dataInputStream2.readInt();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(code + "");
}
});
if (code == 0) {
final double latitude = dataInputStream2.readInt() / 1000000D;
final double longitude = dataInputStream2.readInt() / 1000000D;
setLocation(new Coordinates(latitude, longitude, 0.0f));
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(latitude+"-----"+longitude);
}
});
dataInputStream2.readInt();
dataInputStream2.readInt();
dataInputStream2.readUTF();
} else {
System.out.println("Error obtaining Cell Id ");
}
outputStream2.close();
inputStream2.close();
} catch (Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
private void tryGetLocationFromDevice() {
_gotLocation = false;
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
LocationProvider myLocationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = myLocationProvider.getLocation(300);
setLocation(myLocation.getQualifiedCoordinates());
} catch ( InterruptedException iex ) {
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
if (!_gotLocation) {
getLocationFromGoogle();
}
}
public void run() {
int bbMapsHandle = CodeModuleManager.getModuleHandle("net_rim_bb_lbs"); // OS 4.5 - 6.0
int bbMapsHandle60 = CodeModuleManager.getModuleHandle("net_rim_bb_maps"); // OS 6.0
if (bbMapsHandle > 0 || bbMapsHandle60 > 0) {
tryGetLocationFromDevice();
} else {
getLocationFromGoogle();
}
}
}
private void writeDataGoogleMaps(OutputStream out, int cellID, int lac) throws IOException {
DataOutputStream dataOutputStream = new DataOutputStream(out);
dataOutputStream.writeShort(21);
dataOutputStream.writeLong(0);
dataOutputStream.writeUTF("en");
dataOutputStream.writeUTF("Android");
dataOutputStream.writeUTF("1.0");
dataOutputStream.writeUTF("Web");
dataOutputStream.writeByte(27);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(3);
dataOutputStream.writeUTF("");
dataOutputStream.writeInt(cellID);
dataOutputStream.writeInt(lac);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.writeInt(0);
dataOutputStream.flush();
}
}
Your GPSThread object is currently declared as a private inner class within GPSHandler. If you want to stop execution (or indeed do anything with it) from outside the scope of GPSHandler you will need to mark it as public. You will also need to provide some public mechanism (e.g. a stop() method) to cancel the thread execution.
The most common way of doing this is to have a boolean flag inside your thread (e.g shouldStop) which is checked within your main execution loop inside run() to see if it should stop. When the stop() method is called shouldStop is set to true and your Thread will stop.
Here's a good example: How to stop threads in Java?
There's two groups of changes you should make.
Change the Stop Requested Flag
First, remember that encapsulation is a good thing in Object-Oriented languages. The isStopRequested() method, or stopRequested variable of the GPSHandler should not be used outside of that class. Your UI's GPSListener should not attempt to use either of those. I would change your GPSHandler to use this:
private static boolean stopRequested = false;
public synchronized static void requestStop() {
stopRequested = true;
}
private synchronized static boolean isStopRequested() {
return stopRequested;
}
Only requestStop() should be public. It looks like you made stopRequested public to allow the GPSListener to reset it. If it needs resetting, let the class that owns that variable do the resetting. For example, in GPSHandler:
/** call this to trigger a new location fix */
public void requestLocationUpdates() {
if (_gpsThread == null || !_gpsThread.isAlive()) {
// reset this stop flag:
stopRequested = false;
_gpsThread = new GPSThread();
_gpsThread.start();
}
}
requestLocationUpdates() is really the method that starts the thread, so it should be where stopRequested gets reset to false.
Also, another reason that you should not make stopRequested public and allow other classes to use it is that this is not generally thread-safe. One of the reasons to wrap stopRequested with the requestStop() and isStopRequested() methods is to add thread-safety. There's many ways to do that, but those two methods achieve thread-safety by being marked with the synchronized keyword.
Change How/Where You Check the Flag
After you make these fixes, you need to change where you check if a stop has been requested. You don't really want to check isStopRequested() in the refreshCoordinates() method. That method involves almost no work. Even though it starts the process of getting a location fix, that only starts a thread, but the actual work of getting the location is done on a background thread (your GPSThread). If requestStop() is called, it's very unlikely that it will be called in the middle of refreshCoordinates(), so that's not where you should check it.
Check isStopRequested() multiple times within the GPSHandler class's methods tryGetLocationFromDevice() and getLocationFromGoogle(). Those are the methods that perform slow processing. Those are the ones you might want to interrupt in the middle. So, something like this:
private void getLocationFromGoogle() {
try {
int cellID = GPRSInfo.getCellInfo().getCellId();
int lac = GPRSInfo.getCellInfo().getLAC();
String urlString2 = "http://www.google.com/glm/mmap";
if (isStopRequested()) return;
// Open a connection to Google Maps API
ConnectionFactory connFact = new ConnectionFactory();
ConnectionDescriptor connDesc;
connDesc = connFact.getConnection(urlString2);
HttpConnection httpConn2;
httpConn2 = (HttpConnection)connDesc.getConnection();
httpConn2.setRequestMethod("POST");
// Write some custom data to Google Maps API
OutputStream outputStream2 = httpConn2.openOutputStream();//getOutputStream();
writeDataGoogleMaps(outputStream2, cellID, lac);
if (isStopRequested()) return;
// Get the response
InputStream inputStream2 = httpConn2.openInputStream();//getInputStream();
DataInputStream dataInputStream2 = new DataInputStream(inputStream2);
// Interpret the response obtained
dataInputStream2.readShort();
dataInputStream2.readByte();
if (isStopRequested()) return;
final int code = dataInputStream2.readInt();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
Dialog.alert(code + "");
}
});
And in tryGetLocationFromDevice(), you could do this (make sure to add the member variable and new method below):
private LocationProvider _locationProvider; // must be a member variable!
public void requestStop() {
if (_locationProvider != null) {
// this will interrupt the _locationProvider.getLocation(300) call
_locationProvider.reset();
}
}
private void tryGetLocationFromDevice() {
_gotLocation = false;
try {
Criteria myCriteria = new Criteria();
myCriteria.setCostAllowed(false);
_locationProvider = LocationProvider.getInstance(myCriteria);
try {
Location myLocation = _locationProvider.getLocation(300);
setLocation(myLocation.getQualifiedCoordinates());
} catch ( InterruptedException iex ) {
// this may be caught if stop requested!!!!
System.out.println(iex.getMessage());
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
} catch ( LocationException lex ) {
System.out.println(lex.getMessage());
}
if (!_gotLocation && !isStopRequested()) {
getLocationFromGoogle();
}
}
Then, call the GPSThread.requestStop() method from the outer GPSHandler.requestStop() method:
public synchronized static void requestStop() {
stopRequested = true;
if (_gpsThread != null) {
_gpsThread.requestStop();
}
}

Passing a string from web part to user control

public class ToolPartGetLists : Microsoft.SharePoint.WebPartPages.WebPart, ICommunicationInterface
{
private bool _error = false;
//.........
protected override void CreateChildControls()
{
if (!_error)
{
try
{
ViewState["prodList"] = SelectedList;
//base.CreateChildControls();
Office_Cp = (OfficeCPS)Page.LoadControl(#"/_controltemplates/OfficeCP/OfficeCP.ascx");
this.Controls.Add(Office_Cp);
// Your code here...
//this.Controls.Add(new LiteralControl(this.MyProperty));
}
catch (Exception ex)
{
HandleException(ex);
}
}
}
}
public class OfficeCPS : System.Web.UI.UserControl
{
//I want the value of Selected List here
public string prodDataList = "";
//.......
}
I tried ViewState, not working!!!
Inside the try you could use:
Office_Cp = (OfficeCPS)Page.LoadControl(#"/_controltemplates/OfficeCP/OfficeCP.ascx");
this.Controls.Add(Office_Cp);
Office_Cp.prodDataList = SelectedList;
If this doesn't work pay careful attention to how you are handling the ASP.NET lifecycle.
Also note it would be better practice to hide prodDataList behind a property or method.

Resources