so.. I have a checkboxSelectionGrid like the one in this link: http://gwt-ext.com/demo/#checkboxSelectionGrid
I want to select multiple post tex all with the same company.
how do I do that?
Well, it is a little unclear as to whether you are wanting to preselect several with the same company name, or do something with them afterwards, but here is how I went about doing it. Perhaps it will be of some use to someone.
Note I'm using Reversible Fees, not Companies per the linked code, but the concept is the same.
private GridEx fees;
private GridEx<BeanModel> fees;
.
.
.
fees.getStore().add(feeItems); // this finishes adding all the items.
List<BeanModel> preselectedItems = new ArrayList<BeanModel>();
for (BeanModel feeItem : (fees.getStore() != null && fees.getStore().getModels() != null) ? fees.getStore().getModels() : Collections.<BeanModel>emptyList()) {
if (feeItem.<ReversibleFee>getBean().isSelected()) {
preselectedItems.add(feeItem);
}
}
fees.getSelectionModel().select(preselectedItems, false);
If you are wanting to do something with the data every time a checkbox is checked, you can do it like so:
fees.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BeanModel>() {
#Override
public void selectionChanged(SelectionChangedEvent<BeanModel> beanModelSelectionChangedEvent) {
feeTotal.setValue(0);
for (BeanModel anItem : fees.getStore().getModels()) {
if (beanModelSelectionChangedEvent.getSelection().contains(anItem)) {
anItem.<ReversibleFee>getBean().setSelected(true);
feeTotal.setValue(feeTotal.nullSafeGetValue() + Math.abs(anItem.<ReversibleFee>getBean().getAmount()));
} else {
anItem.<ReversibleFee>getBean().setSelected(false);
}
}
}
});
And finally, if you're wanting to do something with the data after submit, you can do it like so:
for (BeanModel beanModel : fees.getSelectionModel().getSelectedItems()) {
beanModel.<ReversibleFee>getBean().setAmount(788);
}
Related
I've implemented a soft delete behavior in my imaginary Video rental app, and now I am trying to implement a way to reactivate my "deleted" customers, but I can't get my approach to work, surely something simple, but google did not let me find the answer, so here I am.
Here is an excerpt from my repo interface (JpaRepository):
#Query("select m from Movie m where m.isDeleted = true")
List<Movie> findAllIsDeleted();
#Override
#Query("select m from Movie m where m.isDeleted=false")
List<Movie> findAll();
#Modifying
#Transactional
#Query("update Movie m set m.isDeleted=true where id=?1")
void softDelete(Long id);
In my service class I have:
public List<Movie> findAllMovies(String filterText) {
if (filterText == null || filterText.isEmpty()) {
return movieRepository.findAll();
} else {
return movieRepository.search(filterText);
}
}
public List<Movie> findAllDeletedMovies() {
return movieRepository.findAllIsDeleted();
}
And an excerpt from my listview class looks like:
...
Checkbox showDeleted = new Checkbox("Show deleted movies", e -> {
updateList();
Notification.show(e.getValue().toString());
});
...
private void updateList() {
if (showDeleted.getValue() == true) {
grid.setItems(service.findAllDeletedMovies());
}
grid.setItems(service.findAllMovies(filterText.getValue()));
}
But obviously there is something wrong in the listener part, or there is a silent "sure we want to help feature" that I am not aware of. Because the updateList function is not executed. What have I missed?
The problem lies in the implementation of your updateList method.
No matter if the value of the checkbox is true, at the end it always sets the items again that are returned by service::findAllMovies.
move the last statement into an else block and it should work.
private void updateList() {
if (showDeleted.getValue()) { // btw, if(boolValue == true) is redundant. just do if(boolValue)
grid.setItems(service.findAllDeletedMovies());
} else {
grid.setItems(service.findAllMovies(filterText.getValue()));
}
}
I Don’t Know you data table design,
but you can try this
"select m.* from Movie m where m.isDeleted = true"
I refresh to android billing version 4 and 2 things are not working anymore.
First I have this:
else if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED) {
Purchase.PurchasesResult queryAlreadyPurchasesResult = billingClient.queryPurchases(INAPP); // deprecated
List<Purchase> alreadyPurchases = queryAlreadyPurchasesResult.getPurchasesList();
if(alreadyPurchases!=null){
handlePurchases(alreadyPurchases);
}
}
queryPurchases is deprecated.
Second I have this:
void handlePurchases(List<Purchase> purchases) {
for(Purchase purchase:purchases) {
//if item is purchased
if (PRODUCT_ID.equals(purchase.getSku()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED)
{
if (!verifyValidSignature(purchase.getOriginalJson(), purchase.getSignature())) {
// Invalid purchase
// show error to user
Toast.makeText(getApplicationContext(), R.string.plus_error, Toast.LENGTH_SHORT).show();
return;
}
getSku() was working, but now it is mark as Cannot resolve method getSku() in Purchase
Any ideas how to solve this issues?
From docs:
Summary of changes
Added BillingClient.queryPurchasesAsync() to replace BillingClient.queryPurchases() which will be removed in a future release.
Added Purchase#getSkus() and PurchaseHistoryRecord#getSkus(). These replace Purchase#getSku and PurchaseHistoryRecord#getSku which have been removed.
But I don't know how to apply this new commands in my code above.
If I change getSku to getSkus my if if (PRODUCT_ID.equals(purchase.getSkus()) && purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED) will say that it is always false. And I have no idea how to use queryPurchasesAsync(), need 2 params now.
Thanks.
As I mentioned earlier in a comment you are comparing a String to a List object, but as chitgoks said it is ArrayList<String> and not List<String> as i assumed. I'm not sure if you would ever get more than one sku-string (since you probably don't order multiple things at the same time?) but either look trough them all to be sure or take a chance and compare PRODUCT_ID with only purchase.getSkus().get(0).
The new async call for purchases seems to require only small changes.
Example of old way to do it:
Purchase.PurchasesResult result = billingClient.queryPurchases(BillingClient.SkuType.SUBS);
doSomethingWithPurchaseList(result.getPurchasesList());
And this would be the new way to do the same:
billingClient.queryPurchasesAsync(BillingClient.SkuType.SUBS, new PurchasesResponseListener() {
#Override
public void onQueryPurchasesResponse(#NonNull BillingResult billingResult, #NonNull List<Purchase> list) {
doSomethingWithPurchaseList(list);
}
});
getSkus returns an ArrayList<String>. Please use contains as below.
purchase.getSkus().contains(YOUR_PRODUCT_ID.toLowerCase())
Posting this a year in. As with billing 4.0.0, the documentation 'Integrate the Google Play Billing Library into your app' as of billing 5.0.0 is buggy and incomplete, although possibly not as bad as a year ago. Now we are dealing with ProductDetails instead of SkuDetails objects. Also note the following corrections in documentation:
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.of(
should be:
QueryProductDetailsParams queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
ImmutableList.from,(//'from' instead of 'of'
...
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
ImmuableList.of(
should be:
BillingFlowParams billingFlowParams =
BillingFlowParams.newBuilder()
.setProductDetailsParamsList(
ImmutableList.from(//'ImmutableList.from' instead of 'ImmuableList.of'
...
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
public void onProductDetailsResponse(BillingResult billingResult,
List<ProductDetails> productDetailsList) () {
should be:
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
public void onProductDetailsResponse(BillingResult billingResult,
List<ProductDetails> productDetailsList) {//no extra parens
...
//Incomplete
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(ProductType.SUBS)
.build(),
/* purchaseResponseListener= */ this
);
// PurchaseResponseListener implementation.
public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) {
// check BillingResult
// process returned purchase list, e.g. display the plans user owns
}
The most disappointing part of documentation IMHO. It just gives clues and the 'this' is missleading, you will get an error with the suggestion to cast purchaseResponseListener to it. An actual implementation would be:
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder()
.setProductType(BillingClient.ProductType.INAPP)//or SUBS
.build(),
new PurchasesResponseListener() {
#Override
public void onQueryPurchasesResponse(BillingResult billingResult, List<Purchase> purchases) {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK&&purchases != null) {
for (Purchase purchase : purchases) {
handlePurchase(purchase);
}
}
}
}
);
In your code, 'purchase.getSku' won't be recognized as the method was 'purchase.getSkus()'. This is depreciated now anyways and you would use the following to pull the product id (sku) off. Likely you will have just one product for a puchase object, although users can now buy multiple products with a single purchase:
purchase.getProducts().get(0)
So you all know new billing library has new feature
every thing will be in background thread so do not do change anything on main UI during acknowledgement of purchase and restoring purchase.
if you are giving consumable purchase then user can now buy same sku in more quantity in one purchase so write logic accordingly. use getQuantity() function.
to restore non consumable.
billingClient.queryPurchasesAsync(
BillingClient.SkuType.INAPP,
new PurchasesResponseListener() {
#Override
public void onQueryPurchasesResponse(#NonNull BillingResult billingResult, #NonNull List < Purchase > myPurchases) {
if (!myPurchases.isEmpty()) {
for (Object p: myPurchases) {
final Purchase purchase = (Purchase) p;
if (purchase.getPurchaseState() == Purchase.PurchaseState.PURCHASED && purchase.getSkus.contains("sku here") {
handlePurchase(purchase);
}
}
});
}
}
)
I want the LiveData source for a RecyclerView to change depending on which list you selected. And that if you've selected a source in this search.
At the moment I can't switch back and forth between the sources. So I can display items from my Room database, but I can't change the source if I've selected another list.
Example: If you selected List 2, the LiveData source will be changed and all items contained in that List 2 will be displayed. Now you should also be able to search for words in this list 2. How can you do this during the runtime of an app?
A part of my current Repository:
public LiveData<List<VocabularyEntity>> getVocabularies(int listNumber, String searchText) {
if (listNumber == 0) {
return listDao.getVocabularies(searchText);
} else {
return listDao.getVocabularyList(listNumber, searchText);
}
}
And a part of my current ViewModel:
public LiveData<List<ListEntity>> getLists() {
return repository.getLists(listNumber, searchText);
}
I do not see any setValue or getValue function that is being called on your LiveData actually.
In order to change the LiveData to interact with the live changes, you need to call the setValue in your LiveData object. Something like the following should fix your problem here I think.
// I am assuming you have this variable declared in your viewmodel
private LiveData<List<ListEntity>> vocabList;
public LiveData<List<ListEntity>> getLists() {
List<ListEntity> vocabListFromDB = repository.getLists(listNumber, searchText);
vocabList.setValue(vocabListFromDB);
return vocabList;
}
And you do not have to return the LiveData object from the repository function anymore.
public List<VocabularyEntity> getVocabularies(int listNumber, String searchText) {
if(listNumber == 0) {
return listDao.getVocabularies(searchText);
} else {
return listDao.getVocabularyList(listNumber, searchText);
}
}
I hope that helps!
I want to share my personal opinion on implementing this actually. I would rather have a ContentObserver instead of a LiveData setup. Implementation with a ContentObserver and a CursorLoader looks like an easier and robust solution in my humble opinion.
Is there a better way to check/detect if entity was updated in db? The reason being is the system publishes any changes to an external webservice, we dont want to publish if there is no changes as the webservice is slow to respond (we want to keep the soap body light as we are posting variable text lenght).
My current approach is described below:
For a given entity:
public class Comment {
int id;
String text;
}
In my service class I will detect it like so:
public class CommentServiceImpl {
void saveList(List<Comment> comments) {
for(Comment c : comments) {
Comment existing = this.findById(c.id);
if (existing != null) {
boolean nochange = existing.getText().equals(c.getText());
if (nochange) {
//do nothing, we don't want to publish to external webservice
} else {
this.save(c);
externalWs.publish(c);
}
}
}
}
This is not an answer in JPA but, if u are using Oracle, DCN is a pretty good api. Check it:
http://docs.oracle.com/cd/E11882_01/java.112/e16548/dbchgnf.htm
I am not experienced in xml parsing so maybe some of the things I write look stupid to some and maybe some of my terminology is not quite correct.. Please forgive.
I develop an android app, which needs among others to parse weather data from YR.no. This organization offers an api with methods that provide certain data on xml format. Let’s say for example I want to parse xml data from this http://api.yr.no/weatherapi/seaapproachforecast/1.0/?location=stad
I developed a code that can do some xml parsing and it works right in this http://www.w3schools.com/xml/simple.xml (as a test).
The main code lines to define what to get in my BaseFeedParser class are:
RootElement root2 = new RootElement("breakfast_menu");
Element food = root2.getChild("food");
Element name = food.getChild("name");
food.setEndElementListener(new EndElementListener() {
public void end() {
messages.add(currentMessage.copy());
}
});
food.getChild("name").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentMessage.setTitle(body);
}
});
try {
Xml.parse(this.getInputStream(), Xml.Encoding.ISO_8859_1, root2.getContentHandler());
} catch (Exception e) {
throw new RuntimeException(e);
}
return messages;
And then from my activity class:
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
loadFeed();
}
private void loadFeed() {
try {
BaseFeedParser parser = new BaseFeedParser();
messages = parser.parse();
List<String> titles = new ArrayList<String>(messages.size());
System.out.println(messages.size());
for (Message msg : messages) {
titles.add(msg.getTitle());
}
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(this, R.layout.row,titles);
this.setListAdapter(adapter);
String str = "!";
if (titles != null) {
str = titles.toString();
System.out.println("not null");
System.out.println(str);
}
test(str);
} catch (Throwable t) {
Log.e("AndroidNews",t.getMessage(), t);
}
}
public void test(String s) {
setContentView(R.layout.error);
TextView textView = (TextView) findViewById(R.id.mytextview);
textView.setText(s);
}
So it returns and prints the data I want (“Belgian Waffles” etc)
My problem with the yr.no data that I originally wanted to parse is that every end child does not contain just one value but can have more tags (e.g. <waveDirection unit="degree" value="250"/>). So when I change the elements to use this one, it ends to 25 different Strings (which if you count are all the different children with tag waveDirection) but every value is empty (like a String a = ""). I get no error, I just get a list of 25 empty strings. The way I try to reach my element is something like:
RootElement root = new RootElement("weatherdata");
Element product = root.getChild("product");
Element time = product.getChild("time");
Element location = time.getChild("location");
location .setEndElementListener(new EndElementListener(){
public void end() {
messages.add(currentMessage.copy());
}
});
location.getChild("windDirection").setEndTextElementListener(new EndTextElementListener() {
public void end(String body) {
currentMessage.setTitle(body);
}
});
So how should I modify this so that it works with this xml? I do not provide all the classes and methods (like setTitle()) but I think they work since they parse right my first test xml. And I suppose I set my feedUrlString = "http://api.yr.no/weatherapi/seaapproachforecast/1.0/?location=stad"; correctly since it finds the root of the document and 25 elements.
EDIT: I did it! The right way to get the attributes was to use:
location.setStartElementListener(new StartElementListener(){
public void start(Attributes attributes){
messages.add(currentMessage.copy());
}
});
location.getChild("windDirection").setTextElementListener(new TextElementListener(){
public void end(String body) {
//currentMessage.setTitle(body);
//System.out.println("b="+ body);
}
#Override
public void start(Attributes attributes) {
System.out.println("val" + attributes.getValue("deg"));
currentMessage.setTitle(attributes.getValue("deg"));
}
});
So now I get my data but for some reason all except the very last element (I tested it for other YR.no xmls as well).. There must be some bug that I should solve but the major step is done. Thank you all for the answers and especially user306848 who pointed me to the direction I used!
Use Dom Parser.......It will be easy...
See some tutorial from here,
http://www.roseindia.net/xml/dom/
I think your code assumes there is text node which represents the values you seek. Which is not the case for the xml file from the yr.no domain.
You need to figure out how to read attributes from tags for the xml library you use.
I have no experience with android development, but do you use the android.sax package? Then i think android.sax.StartElementListener would be a good candidate. It receives the attributes that belong to a specific tag.
Use this example.
He is using a XML file stored locally. If your getting a XML Feed change the code to the following:
URL url = new URL("ENTER XML LINK");
InputStream stream = url.openStream();
Document doc = docBuilder.parse(stream);