How to set list of map into javafx table view - list

The following code snippets show the declarations of the fields and how I set up the table.
Please tell me what went wrong. The data is not getting displayed.
#FXML
private TableColumn<Map<String, Object>, String> productNameCol ;
#FXML
private TableColumn<Map<String,Object>, String> requestedBarcodeCol;
#FXML
private TableColumn<Map<String,Object>, String> pickedBarcodeCol;
productNameCol.setCellValueFactory(new PropertyValueFactory<Map<String,Object>,String>("ProductName"));
requestedBarcodeCol.setCellValueFactory(new PropertyValueFactory<Map<String,Object>,String>("ActualBarcode"));
pickedBarcodeCol.setCellValueFactory(new PropertyValueFactory<Map<String,Object>,String>("PickedBarcode"));
requestedQuantityCol.setCellValueFactory(new PropertyValueFactory<Map<String,Object>,String>("ActualQuantity"));
actualQuantityCol.setCellValueFactory(new PropertyValueFactory<Map<String,Object>,String>("PickedQuantity"));
unMatchDataTableView.setItems(FXCollections.observableArrayList(unmatchedBarcodeMap));

Since the question does not contain a MCVE, I've got to make some assumptions; the solution I present may not work without modifications. Those are my assumptions:
unmatchedBarcodeMap is non-empty
The controller is properly used when loading the fxml
The fields contain the instances used in the TableView that is displayed on screen
PropertyValueFactory uses getters or property getters to retrieve values. These are not available for Map:
Let <property> denote the string passed to the PropertyValueFactory and <Property> the same string but with the first char converted to upper case:
PropertyValueFactory looks for a method named <property>Property that returns a ObservableValue containing the value to be displayed in the column first. If such a method exists, the result of invoking the method on the row item is returned from the call method. If this method is not available, PropertyValueFactory looks for a method named get<Property>; If this method is available, the result of invoking the method for the row item is wrapped in a ObservableValue object and returned from the call method. Otherwise null is returned resulting in an empty cell.
You need to use MapValueFactory instead of PropertyValueFactory to retrieve values from the Maps:
productNameCol.setCellValueFactory((Callback) new MapValueFactory("ProductName"));
...
This displays the result of calling using rowItem.get("ProductName") in the productNameCol column.

Related

Removing non unique Objects from a List (identifiable by a property)

I am capturing events from a stream, each event is a Device Object. The way the stream work is that it is on a timer, so it picks up the same device multiple times and adds to the stream.
I am putting all theres is a List<Device> and putting that into another stream.
I have create a StreamTransformer in the attempt to remove duplicate from the list and then add the unique list back into the stream.
This transform code below, I have tried to add to set and back to list, but this hasn't worked I assume due to the fact they are objects not strings.
//Transform Stream List by removing duplicate objects
final deviceList = StreamTransformer<List<Device>, List<Device>>.fromHandlers(
handleData: (list, sink) {
List<Device> distinctList = list.toSet().toList();
sink.add(distinctList);
});
I have attempted to use .where and other libraries but to no avail and am hoping for some guidance.
Device Object contains unique id and name that could be used to filter
out duplicates
Question: How can I remove duplicate objects from a List in Dart?
Thanks in advance.
First of all you would need to define by which criteria the objects are supposed to be unique. Is there an identifying property for example? If that is the case the following options should work.
The most efficient way is probably to make the approach with a set working. For that you would need to turn your objects into data objects, meaning have them identify for equality by property values. For that you would override the equality operator and hashCode getter. However this changes how your objects behave on every equality operation, so you would have to judge if that is suitable. See this article.
Another option is to just filter manually using a Map:
class MyObj {
String val;
MyObj(this.val);
}
TestListFiltering(){
List<MyObj> l = [
MyObj("a"),
MyObj("a"),
MyObj("b"),
];
// filter list l for duplicate values of MyObj.val property
Map<String, MyObj> mp = {};
for (var item in l) {
mp[item.val] = item;
}
var filteredList = mp.values.toList();
}

How can I accept user input from an NSTextField to instantiate a new object using the stringValue as the variable name?

For example, I have a class "Person", with all its member variables.
I have a UI with an NSTextField and a Submit button. When the user enters a name in the text field and clicks submit, a new "person" object is instantiated, so that
let (NSTextField.stringValue) = Person(name: NSTextField.stringValue)
The idea is to have these "Person" objects stored in an array of objects for later reference and modification.
Alternatively, I have considered of course that each Person object has a string variable "Name", so that creating a new object with the name of another existing object doesn't overwrite anything currently instantiated--but in that case, I need a way to iterate generic names like person1, person2, person3. I'm unable to find anything about how to automate that process either, however.
Whenever you start to think "I need to somehow dynamically create new variables", don't. You probably don't need to do that. Most of the times, you need a kind of data structure.
Here, you want variables with custom names. You should probably use a dictionary. A dictionary is like a real dictionary, you have keys and values. Each key correspond to a value and keys cannot contain duplicates.
A dictionary with String as keys and Person as values should do the job:
var myDictionary = [String: Person]()
Now, instead of doing this:
let (NSTextField.stringValue) = Person(name: NSTextField.stringValue)
you do
myDictionary[NSTextField.stringValue] = Person(name: NSTextField.stringValue)
To access a person, do this:
myDictionary["Tom"]
For more info, see the "Dictionaries" section of this; https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/CollectionTypes.html

How to define a map in Xcore

According to the EMF FAQ, it is possible to create a Map in EMF:
An EMap is basically a List of java.util.Map$Entry instances.
Therefore to create a Map you need to first model your map entry by
following these steps:
Create an EClass with the name [Type1]To[Type2]Map where [Type1] represents the key's type and the [Type2] represents the value's type.
Set the Instance Class Name property of the newly created EClass to java.util.Map$Entry.
Create an EAttribute or EReference named "key" and set the EDataType or EClass for it.
Create an EAttribute or EReference called "value" and set the EDataType or EClass for it.
Now, when you create an EReference somewhere that uses this map entry
class as its EClass, the EMF code generator will detect this special
case and generate a properly typed EMap getter/setter for you instead
of a normal EList getter/setter.
Can I use this with Xcore models? I am not sure whether step #2 is doable in Xcore or whether it supports maps at all.
For me this works.
DataPoints.xcore:
...
class KeyValuePair wraps java.util.Map$Entry {
String key
String value
}
class KeyValueList {
contains KeyValuePair[] entries
}
The above results in a KeyValueListImpl class with a getEntries method that looks like this:
public EMap<String, String> getEntries() {
if (entries == null) {
entries = new EcoreEMap<String,String>(DataPointsPackage.Literals.KEY_VALUE_PAIR, KeyValuePairImpl.class, this, DataPointsPackage.KEY_VALUE_LIST__ENTRIES);
}
return entries;
}

Ordering Sitecore search results

I have a IQueryable<T> object as search results object.
I apply the filtering and sorting on this search object.
Before I call the GetResults(), I want to order the results based on one of the field's (Fieldname - Priority) value. So for all the items in the IQueryable<T> object, I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I have the fieldmap entry for Priority field.
search.OrderByDescending(i => !string.IsNullOrEmpty(i.GetItem().GetFieldValue("Priority")))
The above command doesn't work. Apparently, I can't use Sitecore extension methods with IQueryable?
If I convert search.ToList(). Do the ordering and then convert it back to AsQueryable(), I get the following error:
There is no method 'GetResults' on type 'Sitecore.ContentSearch.Linq.QueryableExtensions'
that matches the specified arguments
Is there a neat and quick way to get around this?
Cheers
I think you just need to add your field to your SearchResultItem and mark it as an int. I am making the assumption that the field is an int. Make a custom class that inherits SearchResultItem.
public class CustomSearchResultItem : SearchResultItem
{
[IndexField("Priority")]
public int Priority { get; set; }
}
Then use it in your search. Finally order by it.
using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var results = context.GetQueryable<CustomSearchResultItem>().Where(prod => prod.Content.Contains("search box text").OrderByDescending(t => t.Priority);
}
Some data found here.
http://www.sitecore.net/learn/blogs/technical-blogs/sitecore-7-development-team/posts/2013/10/sorting-and-ordering-results.aspx
You can order search results using multiple fields by using the OrderByDescending combined with ThenByDescending. So you would need to order by Priority and then by [Name|Date|Whatever].
I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.
I sort them first on the criteria chosen by the user - like Name, Date created etc. Once I get the results back, I need to order them by priority field
You are conflicting yourself in the questions and comments. If you want the results with priority first and then by user selected results then the following will work:
query = dataQuery.OrderByDescending(i => i.Title).ThenByDescending(i => i["Priority"]);
var results = query.GetResults().Hits.Select(h => h.Document);
There was a bug in earlier version of Sitecore which meant that the ThenBy clause will be added before the OrderBy clause hence it is added in reverse above. You may want to check if this is fixed in the current version. If so simply change your query to:
query = dataQuery.OrderByDescending(i => i["Priority"]).ThenByDescending(i => i.Title);
You don't have to add the field to your SearchResultItem if you just want to order by it, only if you need the actual value of that field returned to as well.
If you need to order by a custom user supplied value then you can pass in i => i["whatever-field-the-user-has-selected"] instead of i.Title.
You can find more info in this blog post.

FluentNHibernate: HasMany mapping to methods (their backing fields)? / Foreign key not saved

Is it possible to map to methods instead of properties?
I have a Customer class with a method "GetOrders()" typeof "ReadOnlyCollection" with backing field "_orders" typeof "IList".
I tried in CustomerMap:
HasMany<Order>(Reveal.Member<Customer>("_orders"))
.KeyColumn("CustomerId").Cascade.All().Inverse().Not.LazyLoad();
But I get an exception when running the insert for a customer containing 1 order.
Cannot insert the value NULL into column 'CustomerId', table 'Order';
column does not allow nulls. INSERT fails.
Does mapping methods (or at least their backing fields) not work?
Or am I doing something else wrong?
The problem was that I did not map the Customer to the Orders also.