RSSService item with the same key multiple times - codenameone

I have a RSSService with an item like the one show below
<item>
<title>Accessori per la cura della persona</title>
<link>http://www.myurl.it/accessori-per-la-cura-della-persona/</link>
<comments>http://www.myurl.it/accessori-per-la-cura-della-persona/#comments</comments>
<pubDate>Tue, 24 Oct 2017 09:29:44 +0000</pubDate>
<dc:creator><![CDATA[Farmacia Rizzo Davide]]></dc:creator>
<category><![CDATA[News]]></category>
<category><![CDATA[Offerte]]></category>
<category><![CDATA[Callifugo]]></category>
<category><![CDATA[Raspa piedi]]></category>
<category><![CDATA[Spazzola ceramica]]></category>
<category><![CDATA[Spazzola piatta]]></category>
<category><![CDATA[Spazzola tonda]]></category>
<category><![CDATA[Spazzole capelli]]></category>
<guid isPermaLink="false">http://www.myurl.it/?p=3982</guid>
<description>.....
To read all the content I use this:
List<Map> records;
...
records = rss.getResults();
...
for (Map m : records) {
Button b = new Button((String)m.get("title"));
if(((String)m.get("category")).equals(CATEGORY_OFFERTE)){
b.setIcon(iconStar);
} else {
b.setIcon(iconNews);
}
b.addActionListener((l)->{
Boolean can = Display.getInstance().canExecute((String)m.get("link"));
if(can != null && can) {
Display.getInstance().execute((String)m.get("link"));
} else {
ToastBar.Status status = ToastBar.getInstance().createStatus();
status.setMessage("Non riesco a connettermi");
status.setExpires(3000);
status.show();
}
});
recordsContainer.addComponent(b);
}
When I read the key "category" I always get the last entry (in this item "Spazzole capelli").
There is a way to read a key like an array? Something like that:
String[] mc = (String[]) m.get("category");
Thank's in advance for any help.
Davide.

This looks like a missing feature in RSSService that expects to find only one category entry and so it parses it into a hash map which effectively allows only one such entry.
I would suggest implementing your own RSS reading and go to the XML directly to get the full power of the protocol. You can use the existing class as a reference on how to do the RSS/ATOM parsing.

This is my idea
protected void textElement(String text) {
if(lastTag != null && current != null) {
// make "ATOM" seem like RSS
if("summary".equals(lastTag)) {
current.put("details", text);
} else {
if("content".equals(lastTag)) {
current.put("description", text);
} else {
if(current.get(lastTag) != null){
try {
List list = (List) current.get(lastTag);
list.add(text);
current.put(lastTag, list);
} catch (ClassCastException e){ // java.lang.String cannot be cast to java.util.List
List list = new ArrayList();
list.add((String)current.get(lastTag));
list.add(text);
current.put(lastTag, list);
}
} else {
current.put(lastTag, text);
}
}
}
}
}
Used in my Form like this:
for (Map m : records) {
Button b = new Button((String)m.get("title"));
try{
String category = (String)m.get("category");
if(category.equals(CATEGORY_OFFERTE)){
b.setIcon(iconStar);
} else {
b.setIcon(iconNews);
}
} catch (ClassCastException e){ // java.lang.String cannot be cast to java.util.List
b.setIcon(iconNews);
List list = (List) m.get("category");
for(int i=0; i < list.size(); i++){
if(((String)list.get(i)).equals(CATEGORY_OFFERTE)){
b.setIcon(iconStar);
}
}
}
b.addActionListener((l)->{
Boolean can = Display.getInstance().canExecute((String)m.get("link"));
if(can != null && can) {
Display.getInstance().execute((String)m.get("link"));
} else {
ToastBar.Status status = ToastBar.getInstance().createStatus();
status.setMessage("Non riesco a connettermi");
status.setExpires(3000);
status.show();
}
});
recordsContainer.addComponent(b);
}

Related

InvalidCastException when remove item in ObservableCollection

I am doing a project using WPF and Prims.
When remove category in Categories, an error has occurred.
public ObservableCollection<CategoryModel> _categories;
public ObservableCollection<CategoryModel> Categories
{
get { return _categories; }
set
{
SetProperty(ref _categories, value);
}
}
public void OnNavigatedTo(NavigationContext navigationContext)
{
_journal = navigationContext.NavigationService.Journal;
var category = navigationContext.Parameters["categoryAdd"] as CategoryModel;
if (category != null)
Categories.Add(category);
category = navigationContext.Parameters["categoryDelete"] as CategoryModel;
if (category != null)
{
foreach(var elm in Categories)
if (elm.Id == category.Id)
Categories.Remove(elm); //⇒Error here
}
}
Error:
System.InvalidCastException: 'Cannot cast an object of type' System.Windows.Controls.SelectionChangedEventArgs' to type 'SaleManager.Wpf.Admin.Models.CategoryModel'. '
Why does this error occur? How to fix it?
You can't change a collection in a foreach while reading this collection.
you can do this:
var item = Categories.FirstOrDefault(elm=> elm.Id == category.Id);
Categories.Remove(item);
Use a for loop and iterate backwards. elm is supposed to be a CategoryModel:
if (category != null)
{
for (int i = Categories.Count - 1; i >= 0; --i)
{
CategoryModel elm = Categories[i];
if (elm.Id == category.Id)
{
Categories.Remove(elm);
}
}
}

Unity3D: How to go Back or Forward in Array list

I have a gameObject with an ID, the gameObjects are spawned by giving initial ID: 1 , then any after spawned will be +1 so next is ID: 2.
I have two buttons that check current gameObjects ID#, BackOneButton (-1) and PlusOneButton (+1).
Currently it works but only if the array of gameObjects have IDs in order like for example [gameObject-ID:1], [gameObject-ID:2], [gameObject-ID:3]
But since you can self destruct a certain gameObject, here is where the error is --->
Now the array is not in order for example [gameObject-ID:1], [gameObject-ID:3], [gameObject-ID:4]. So if I'm currently in [gameObject-ID:3] and I use the BackOneButton and looks for ID: 2 it won't find it BUT there is ID:1. That's my error, I can't seem to figure out how to handle this.
Basically, How do I handle missing increments and skip over the missing?
Left Button (MinusOneButton)
void ButtonAction_LeftMinusOne()
{
// Get list of all gameObjects and -1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
case "1":
// nothing to go back to, this is ID: 1
break;
default:
// currently in (ID: 2 & Up) second object
int currentID = int.Parse(idObjNumber);
string idBackOne = (currentID - 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idBackOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
Right Button (PlusOneButton)
void ButtonAction_RightPlusOne()
{
// Get list of all objects and +1 current to switch
string objName = manager.currentObjectTransform.name;
string[] splitArray = objName.Split('_');
string idObjNumber = splitArray[1];
switch (idObjNumber)
{
case "0":
// not supposed to be ID: 0
break;
default:
// currently in (ID: 1 & Up) object
int currentID = int.Parse(idObjNumber);
string idPlusOne = (currentID + 1).ToString();
GameObject[] allObjInFull = GameObject.FindGameObjectsWithTag("Object");
if (allObjInFull.Length >= 2)
{
for (int i = 0; i < allObjInFull.Length; i++)
{
if (allObjInFull[i].transform.name.Contains(idPlusOne))
{
// Set Camera
camera.transform.parent = allObjInFull[i].transform.GetChild(0).GetChild(1);
camera.transform.position = allObjInFull[i].transform.GetChild(0).GetChild(1).position;
camera.transform.rotation = allObjInFull[i].transform.GetChild(0).GetChild(1).rotation;
}
}
}
break;
}
}
It would be way better (especially regarding maintenance) and more efficient to have a central manager class with a List<GameObject> where you simply Add and Remove items dynamically. (Since you already seem to have one in manager I would rather extend that one)
public static class ObjectsManager
{
// If you are not concerned about
// capsulation you could ofcourse make this public as well
// but I thought this is cleaner
private static List<GameObject> objects;
// Read-only property
public static int Count
{
get
{
Initialize();
return objects.Count;
}
}
// initialize the list once
// I first had this in e.g. Awake
// but now you can easily use this in multiple scenes
public static void Initialize(bool force reinitialize = false)
{
if(objects != null && ! reinitialize) return;
objects = FindObjectsWithTag("Object").ToList();
}
public static void Add(GameObject newObject)
{
Initialize();
if(objects.Contains(newObject) return;
objects.Add(newObject);
}
public static void Destroy(GameObject toDestroy)
{
Initialize();
if(objects.Contains(toDestroy)
{
objects.Remove(toDestroy);
}
Object.Destroy(toDestroy);
}
public static int IndexOf(GameObject obj)
{
Initialize();
return objects.IndexOf(obj);
}
public static GameObject GetByIndex(int index)
{
Initialize();
// Use modulo to wrap around the index in case
// +1 or -1 exceeds the list ends
// in your case you might not need it
// but I decided to add it to be more flexible
var nextIndex = (index + 1) % objects.Count;
return objects[index];
}
}
Everytime you Instantiate a new object make sure to also call
ObjectsManager.Add(newObject);
and everytime where you destroy an object rather use
ObjectsManager.Destroy(objectToDestroy);
so it is also removed from the list first.
Then you can easily use
var currentIndex = ObjectsManager.IndexOf(certainObject);
to get the current index of an object and simply move through the index (+1, -1)
var nextObject = ObjectsManager.GetByIndex(currentIndex + 1);
var lastObject = Objects manager.GetByIndex(currentIndex - 1);
In case you switch the scene you have reinitialize the list once in order to get rid of null references
ObjectsManager.Initialize(true);
In your example code you would e.g. use something like
void ButtonAction_LeftMinusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == 0)
{
// nothing to do go back to
// Except you want wrap around then simply remove this check
Debug.Log("Already is first object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex - 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}
And accordingly
void ButtonAction_RightPlusOne()
{
GameObject currentObject = manager.currentObjectTransform.gameObject;
int currentIndex = ObjectsManager.IndexOf(currentObject);
if(currentIndex < 0)
{
Debug.LogErrorFormat(this, "Object {0} is not in list!", currentObject.name);
return;
}
if(currentIndex == ObjectsManager.Count - 1)
{
// nothing to do go forward to
// Except you want wrap around then simply remove this check
Debug.Log("Already is last object in list", this);
return;
}
GameObject newObject = ObjectsManager.GetByIndex(currentIndex + 1);
Transform childOfNewObject = newObject.GetChild(0).GetChild(1);
// Set Camera
// Using simply SetParent with parameter worldPositionStays=false
// reduces it to one single call
camera.transform.SetParent( childOfNewObject, false);
}

C# WPF: Create TreeView from text file

I create my TreeViewItems with the class Node . In the example nodes are specified in source code. But how do I do it if the nodes are to be imported from a text file with content like this:
text file content
Any ideas?
I have tried the following.
public MainWindowVM()
{
private ObservableCollection<Node> mRootNodes;
public IEnumerable<Node> RootNodes { get { return mRootNodes; } }
List<string[]> TreeNodes = new List<string[]>();
string[] lines = null;
try
{
lines = System.IO.File.ReadAllLines(MainWindow.TextFilePath , System.Text.Encoding.Default);
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
Environment.Exit(0);
}
if (lines == null || lines.Length == 0)
{
MessageBox.Show("Text file has no content!");
Environment.Exit(0);
}
foreach (var line in lines)
{
TreeNodes.Add(line.Split('|'));
}
Node newNode = null;
Node childNode = null;
Node root = new Node() { Name = TreeNodes[0][0] };
if (TreeNodes[0].Length > 1)
{
newNode = new Node() { Name = TreeNodes[0][1] };
root.Children.Add(newNode);
}
for (int s = 2; s < TreeNodes[0].Length; s++)
{
childNode = new Node() { Name = TreeNodes[0][s] };
newNode.Children.Add(childNode);
newNode = childNode;
}
}
but I get only the first two nodes. I do not know how to build the whole TreeView with a loop.
TreeView
input example
Root|A
Root|B|C
Root|B|D
Root|E
the problem with your code is that you only process TreeNodes[0] element. to process a collection of elements you need a loop
public MainWindowVM()
{
private ObservableCollection<Node> mRootNodes;
public IEnumerable<Node> RootNodes { get { return mRootNodes; } }
string[] lines = null;
try
{
lines = System.IO.File.ReadAllLines(MainWindow.TextFilePath , System.Text.Encoding.Default);
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
Environment.Exit(0);
}
if (lines == null || lines.Length == 0)
{
MessageBox.Show("Text file has no content!");
Environment.Exit(0);
}
Dictionary<string, Node> nodeCache = new Dictionary<string, Node>();
// processing each line
foreach (var line in lines)
{
Node parentNode = null;
string key = null;
// in each line there are one or more node names, separated by | char
foreach (string childNodeName in line.Split('|'))
{
Node childNode;
// names are not unique, we need a composite key (full node path)
key += "|" + childNodeName;
// each node has unique key
// if key doesn't exists in cache, we need to create new child node
if (false == nodeCache.TryGetValue(key, out childNode))
{
childNode = new Node { Name = childNodeName };
nodeCache.Add(key, childNode);
if (parentNode != null)
// each node (exept root) has a parent
// we need to add a child node to parent ChildRen collection
parentNode.Children.Add(childNode);
else
// root nodes are stored in a separate collection
mRootNodes.Add(childNode);
}
// saving current node for next iteration
parentNode = childNode;
}
}
}

Use Kinect to create a digital catalog application

I am creating a WPF application to create digital catalog using kinect v1.8. I am trying to track only a single skeleton using following code:-
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
// Even though we un-register all our event handlers when the sensor
// changes, there may still be an event for the old sensor in the queue
// due to the way the KinectSensor delivers events. So check again here.
if (this.KinectSensor != sender)
{
return;
}
SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame();
if (skeletonFrame == null)
return;
Skeleton[] skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
Skeleton skeleton = (from skl in skeletons
where skl.TrackingState == SkeletonTrackingState.Tracked
select skl).FirstOrDefault();
if (skeleton == null)
return;
Skeleton[] s = new Skeleton[1];
s[0] = skeleton;
if (SkeletonTrackingState.Tracked == s[0].TrackingState)
{
//s1.SkeletonStream.ChooseSkeletons(s[0].TrackingId);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);
}
}
I am getting an exception when I run the code and skeleton gets detected as follows:-
on the line "this.interactionStream.ProcessSkeleton(s, accelerometerReading, skeletonFrame.Timestamp);"
I need to detect only one skeleton and use it for further processing like to access the digital catalog applications.
Thanks in advance.
I have Faced Same Problem By using below code I have track only one skeleton Which is closer to the sensor.and directly assign the closest skeleton to the main skeleton stream.
private void SensorSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs skeletonFrameReadyEventArgs)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = skeletonFrameReadyEventArgs.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletons != null)
{
//Console.WriteLine(skeletonFrame.SkeletonArrayLength);
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletons);
TrackClosestSkeleton();
Skeleton[] singleSkeleton = new Skeleton[6];
Skeleton skl=(from mno in this.skeletons where mno.TrackingState==SkeletonTrackingState.Tracked && mno.TrackingId==globalClosestID select mno).FirstOrDefault();
if (skl == null)
return;
//Creating an empty skkeleton
Skeleton emptySkeleton = new Skeleton();
singleSkeleton[0] = skl; //Pass the Tracked skeleton with closestID
singleSkeleton[1] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[2] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[3] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[4] = emptySkeleton; //Passing Empty Skeleton
singleSkeleton[5] = emptySkeleton; //Passing Empty Skeleton
this.snew.SkeletonStream.ChooseSkeletons(globalClosestID);
var accelerometerReading = this.KinectSensor.AccelerometerGetCurrentReading();
this.interactionStream.ProcessSkeleton(singleSkeleton, accelerometerReading, skeletonFrame.Timestamp);
}
}
}
int globalClosestID = 0;
private void TrackClosestSkeleton()
{
if (this.snew != null && this.snew.SkeletonStream != null)
{
if (!this.snew.SkeletonStream.AppChoosesSkeletons)
{
this.snew.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletons.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.snew.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
globalClosestID = closestID;
}
}
}
check the above code it works for me.It may helpful to you.Here snew is the Kinectsensor.
You should try to track the closest skeleton using this method from MSDN
private void TrackClosestSkeleton()
{
if (this.kinect != null && this.kinect.SkeletonStream != null)
{
if (!this.kinect.SkeletonStream.AppChoosesSkeletons)
{
this.kinect.SkeletonStream.AppChoosesSkeletons = true; // Ensure AppChoosesSkeletons is set
}
float closestDistance = 10000f; // Start with a far enough distance
int closestID = 0;
foreach (Skeleton skeleton in this.skeletonData.Where(s => s.TrackingState != SkeletonTrackingState.NotTracked))
{
if (skeleton.Position.Z < closestDistance)
{
closestID = skeleton.TrackingId;
closestDistance = skeleton.Position.Z;
}
}
if (closestID > 0)
{
this.kinect.SkeletonStream.ChooseSkeletons(closestID); // Track this skeleton
}
}
}
And then in your SkeletonFrameReady
private void SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
Skeleton[] skeletons = new Skeleton[0];
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null && this.skeletonData != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
// Set skeleton datas from skeletonFrame
skeletonFrame.CopySkeletonDataTo(this.skeletonData);
TrackClosestSkeleton();
}
}
//Do some stuff here
}

store data in array from another class method

i have one method in class call Class1 like
' public void getEventFromUser() {
int event;
Scanner input = new Scanner(System.in);
date.getDateFromUser();
// od.inputday();
// od.inputyear();
time.getTimeFromUser();
System.out.println("Enter description :");
description = input.nextLine();
}'
and i want to execute this method and store in array in another class
like
public void addEvent() {
if (numEvent == maxEvent) {
System.out.println("error…no more room to add events");
} else {
schedule[numEvent]=getEventFromUser();
int count = 0;
while (count < numEvent - 1) {
if (schedule[numEvent].isEqual(schedule[count])) {
isFound = true;
break;
}
count++;
if (isFound == true) {
System.out.println("Event already exists-notadding");
schedule[numEvent] = null;
} else {
schedule[numEvent].setDate();
schedule[numEvent].setTime();
schedule[numEvent].setDescription();
numEvent++;
//schedule[numEvent]=schedule[numEvent].getEventFromUser();
}
}
}
} '
so,how can i do this?
pls give me some solution
getEventFromUser() doesn't return a value, which is why schedule[numEvent]=schedule[numEvent].getEventFromUser() is giving you trouble.
Without knowing a bit more about what you're trying to do, it's hard to say if you should have getEventFromUser() return a value or have getEventFromUser() directly store a value in a field in the class. (I'm guessing the setDate, setTime and setDescription methods do this.)

Resources