I'm new to Blackberry and I'm currently working on it. I have an ObjectChoiceField that uses a string array as its dataset. How can i update the display of the ObjectChoiceField list based on the change of array elements?
I want to do similar thing like notifyDataSetChanged() on Android development.
Update your ObjectChoiceField instance (let say myObjectChoiceField), via setChoices(String[] newChoices) method. Assume newChoicesStringArray is a String array with new option values.
Application.getApplication().invokeLater(new Runnable() {
public void run() {
myObjectChoiceField.setChoices(newChoicesStringArray);
}
});
invokeLater() is used to avoid UI event locking upong field update action.
Related
As the title says I am using PageFactory to initialize my elements.
When I use PageFactory.initElements on the page I want to use my elements everything is fine and works correctly, but when I try to create a new class with PageFactory to have it initialize all elements there I get a null pointer exception.
Below you will find the code I am using:
Actions.java
TestIds testIds = new TestIds();
public void initElements(WebDriver driver) {
PageFactory.initElements(driver, cashierIds);
}
The above lines work when included in my Actions class but when I create a new Class called ElementInitialization.java, move everything in it and then call it my elements throw nullPointerException.
Is there a different way to call the specific faction to work everywhere?
This is my structure of the firestore database:
Expected result: to get all the jobs, where in the experience array, the lang value is "Swift".
So as per this I should get first 2 documents. 3rd document does not have experience "Swift".
Query jobs = db.collection("Jobs").whereArrayContains("experience.lang","Swift");
jobs.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
//Always the queryDocumentSnapshots size is 0
}
});
Tried most of the answers but none worked out. Is there any way to query data in this structure? The docs only available for normal array. Not available for array of custom object.
Actually it is possible to perform such a query when having a database structure like yours. I have replicated your schema and here are document1, document2, and document3.
Note that you cannot query using partial (incomplete) data. You are using only the lang property to query, which is not correct. You should use an object that contains both properties, lang and years.
Seeing your screenshot, at first glance, the experience array is a list of HashMap objects. But here comes the nicest part, that list can be simply mapped into a list of custom objects. Let's try to map each object from the array to an object of type Experience. The model contains only two properties:
public class Experience {
public String lang, years;
public Experience() {}
public Experience(String lang, String years) {
this.lang = lang;
this.years = years;
}
}
I don't know how you named the class that represents a document, but I named it simply Job. To keep it simple, I have only used two properties:
public class Job {
public String name;
public List<Experience> experience;
//Other prooerties
public Job() {}
}
Now, to perform a search for all documents that contain in the array an object with the lang set to Swift, please follow the next steps. First, create a new object of the Experience class:
Experience firstExperience = new Experience("Swift", "1");
Now you can query like so:
CollectionReference jobsRef = rootRef.collection("Jobs");
jobsRef.whereArrayContains("experience", firstExperience).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Job job = document.toObject(Job.class);
Log.d(TAG, job.name);
}
} else {
Log.d(TAG, task.getException().getMessage());
}
}
});
The result in the logcat will be the name of document1 and document2:
firstJob
secondJob
And this is because only those two documents contain in the array an object where the lang is set to Swift.
You can also achieve the same result when using a Map:
Map<String, Object> firstExperience = new HashMap<>();
firstExperience.put("lang", "Swift");
firstExperience.put("years", "1");
So there is no need to duplicate data in this use-case. I have also written an article on the same topic
How to map an array of objects from Cloud Firestore to a List of objects?
Edit:
In your approach it provides the result only if expreience is "1" and lang is "Swift" right?
That's correct, it only searches for one element. However, if you need to query for more than that:
Experience firstExperience = new Experience("Swift", "1");
Experience secondExperience = new Experience("Swift", "4");
//Up to ten
We use another approach, which is actually very simple. I'm talking about Query's whereArrayContainsAny() method:
Creates and returns a new Query with the additional filter that documents must contain the specified field, the value must be an array, and that the array must contain at least one value from the provided list.
And in code should look like this:
jobsRef.whereArrayContainsAny("experience", Arrays.asList(firstExperience, secondExperience)).get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (QueryDocumentSnapshot document : task.getResult()) {
Job job = document.toObject(Job.class);
Log.d(TAG, job.name);
}
} else {
Log.d(TAG, task.getException().getMessage());
}
}
});
The result in the logcat will be:
firstJob
secondJob
thirdJob
And this is because all three documents contain one or the other object.
Why am I talking about duplicating data in a document it's because the documents have limits. So there are some limits when it comes to how much data you can put into a document. According to the official documentation regarding usage and limits:
Maximum size for a document: 1 MiB (1,048,576 bytes)
As you can see, you are limited to 1 MiB total of data in a single document. So storing duplicated data will only increase the change to reach the limit.
If i send null data of "exprience" and "swift" as "lang" will it be queried?
No, will not work.
Edit2:
whereArrayContainsAny() method works with max 10 objects. If you have 30, then you should save each query.get() of 10 objects into a Task object and then pass them one by one to the to the Tasks's whenAllSuccess(Task... tasks).
You can also pass them directly as a list to Tasks's whenAllSuccess(Collection> tasks) method.
With your current document structure, it's not possible to perform the query you want. Firestore does not allow queries for individual fields of objects in list fields.
What you would have to do is create an additional field in your document that is queryable. For example, you could create a list field with only the list of string languages that are part of the document. With this, you could use an array-contains query to find the documents where a language is mentioned at least once.
For the document shown in your screenshot, you would have a list field called "languages" with values ["Swift", "Kotlin"].
I'm trying to create a Solr collection on SolrCloud, and I want to pass in the hosts I want the collection to exist on in a certain order, and have Solr follow that order. Solr exposes this functionality in the API with the parameter createNodeSet.shuffle, but I can't explicitly set this parameter in a SolrAdminRequest.Create instance.
Does this functionality not exist within Solrj? Can I set the value with the setProperties() method even though it's a "param"?
I'm facing this problem too, and I notice that you had opened a PR on the GitHub. I've tried several ways to achieve this goal but finally I give up by shuffling the nodes myself, before passing them to the Create request.
In Kotlin:
val nodes = listOf("node1", "node2")
val createNodeSet = nodes.shuffled().joinToString(",")
In Java:
List<String> nodes = Arrays.asList("node1", "node2");
Collections.shuffle(nodes);
String createNodeSet = String.join(",", nodes);
As current Solr now has the constructor marked as protected, only accessible via a static builder, and as I didn't want to have a new class to worry about, I figured out the following way to set the needed parameter.
This method should be usable on many of the other builder created op objects.
Create req = CollectionAdminRequest //
.createCollection(newCollection, newConfigSet, NUM_SHARDS, NUM_REPLICAS);
final SolrParams reqParams = req.getParams();
if (reqParams instanceof ModifiableSolrParams) {
((ModifiableSolrParams) reqParams).set("createNodeSet.shuffle", "false");
}
Problem
On one Form I have a Multilist where each item has a "name" and an "ID number". I'd like my app to do the following:
After I select an item, it will go to the "profile" screen and then it will display all the information about that person, based on the "ID number" that I will get from the Storage.
Question
How can I get the information from the Multilist item I just clicked?
And then, how can I save that info so I can use it in the "before show (Profile screen)" so I can retrieve the info from Storage.
Thnaks
I will suggest you use a MultiButton instead of Multilist, then you can add actionEvent to individual element.
You can save individual element into static variables in the actionEvent and use it in the before show of your profile form. For example:
Declare this globally:
private static String UserName = "";
And initialize it as follows:
Container content = new Container(new BoxLayout(BoxLayout.Y_AXIS));
content.setScrollableY(true);
for (int i = 0; i < YourItemsLength; i++) {
final MultiButton mb = new MultiButton("Blablabla");
mb.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
UserName = mb.getTextLine1(); // or anything you want it to be
//show the profile form here
}
});
content.addComponent(mb);
}
content.revalidate();
In the beforeShow() of profile, call UserName and you should be able to use the value. Do the same for all the values you need.
I totally agree with Diamonds answer and I think that's the best/simplest way to create a list of items. However, if you do still want to use MultiList you need to implement a ListModel or use DefaultListModel.
From your question I assume you just used the MultiList and filled out the values?
In that case when there is an action event on the list you can just get the instance of the list the invoke Map m = (Map)myList.getSelectedItem();
The map should return key/value pairs containing your data. You can have hidden keys within that data simple by naming them differently from rendererd list elements so you can have something like "id" as the key.
So I'm trying to prevent a race condition between applications.
Using IsolationLevel/TransactionScope, I can lock the table the way I need to, but need to run the update operation first, then operate on the list of modified objects.
To do this, I need to run the update and get the list of updated ID's all in one shot.
If I were to try to take the IDs first, that wouldn't lock the table, and another app instance could query for that same list, before they were flagged.
Is there a way to do something like:
//modify some objects
var updatedIds = context.SaveChanges();
//Process updatedIds
Is there a way to do this? I've tried looking through the ObjectContext entries, but after the Save there doesn't seem to be anything.
Maybe I'll have to do an sproc?
This code can go into your Context class and should give you what you need
public override int SaveChanges()
{
using (var scope = new System.Transactions.TransactionScope())
{
//pre processing
var result = base.SaveChanges();
//post processing
scope.Complete();
return result;
}
}