0

ListmodelList shared on multiple components

asked 2017-10-20 19:16:44 +0800

MaurizioB gravatar image MaurizioB
3 2

updated 2017-10-20 21:14:16 +0800

I've noticed a problem by using the same ListModelList as the model of multiple components (combobox/chosenbox) with different selectedItems binding.

Basically changing the selection in one of the component changes the shown selection in every other component sharing the ListModelList as model.

I found a fiddle search for "zkfiddle.org/sample/2tl5ndm/7-ListModelList-used-in-multiple-components#source-1" that reproduce the issue using comboboxes.

Is this a known bug? How do you fix it?

delete flag offensive retag edit

Comments

6 Answers

Sort by ยป oldest newest most voted
0

answered 2017-10-23 10:33:23 +0800

cor3000 gravatar image cor3000
6280 2 7

Hi Maurizio,

this is exactly the expected behavior when sharing the same ListModel implementation between multiple components.

The ListModelList implements the Selectable interface, that's why it keeps track of the current selection and propagates that among all attached components.

If you just want to share the same item list and without sharing the selection, simply use an ArrayList<integer> or Integer[] to share the same items, but have a separate selection state in each combobox.

see -> updated zkfiddle

This conversion from List/Array into a ListModel will automatically happen by the default converter ComboboxModelConverter

If you want to preserve the memory and avoid copying the items into each ListModel you can create a live-ListModel for each combobox referencing the same collection:

modelForComboA = new ListModelList(items, true /*live*/);
modelForComboB = new ListModelList(items, true /*live*/);

see: ListModelList(java.util.List, boolean))

Robert

link publish delete flag offensive edit
0

answered 2017-10-23 15:47:05 +0800

MaurizioB gravatar image MaurizioB
3 2

updated 2017-10-23 15:51:57 +0800

Hi Robert, thank you for the answer, while it is the expected behaviour, the selection doesn't match what is stored in the "selectedItem" variables thus creating a mismatch between the visuals and the Java part.

Because of this mismatch I do not see a use case where it would be beneficial to have the same ListModel shared, but if it is a technical limit of the Selectable, it would be nice to have this mentioned in the documentation.

That said I still need to use the ListModelList for scrolling purposes (I am using listboxes,not comboboxes), so will opt for the different ListModels (maybe live). With this approach adding an element to one of them will not update the others or will they update correctly without losing the scroll?

link publish delete flag offensive edit
0

answered 2017-10-24 15:32:01 +0800

cor3000 gravatar image cor3000
6280 2 7

updated 2017-10-24 15:35:28 +0800

Hi Maurizio,

I am sorry if this sounds like I am arguing with you (this is not my intention) ... I am just trying to explain what is happening and that your current usage won't bring your desired results.

Besides I can imagine scenarios where shared selection state is useful e.g 2 separate navigation controls (a combobox and a tabbox driven by the same model. Providing 2 redundant controls to choose the current tab in a tabbox) - anyway that's a matter of personal preference whether that's useful or not.

Given that: using a ListModel that implements Selectable only keeps track of a single set of selected items. Shared among both models. That's not a limitation, that's a feature intended to keep a model driven UI in synch.

If you combine the approaches selectedItem + sharing a model you simply implemented redundant state that can get out-of-synch or replicate in a unwanted way.

I am not completely clear how that relates to scrolling... maybe you can provide an example showing where a ListModel is needed for scrolling. A listbox is scrollable when the number of items exceeds the visible listbox body (if limited in size).

If you are referring to a "Load on demand" ListModel then sharing the same ListModel for 2 listboxes may also give unexpected results. If both have different scroll positions, then the same model suddenly has to load elements for visible different ranges. Also there separating the models is preferable in my opinion.

I agree that the approach of using a live list model will serve your purpose best - given the details you shared so far.

Robert

link publish delete flag offensive edit
0

answered 2017-10-24 15:41:53 +0800

cor3000 gravatar image cor3000
6280 2 7

to answer:

With this approach adding an element to one of them will not update the others or will they update correctly without losing the scroll?

again I don't see the relation to scrolling.

About adding elements: I can only refer to the related documentation -> adding an element to the Model will affect the inner collection and not vise versa. So if 2 models share the same inner collection this will lead to inconsistencies as well. When adding an element to one model will not notitify the other model that something was added. And if you add/remove then from the other model you are likely to get IndexOutOfBounds exceptions. If you are just referring to adding removing elements from selection then there's no conflict.

If you need separate items, simply use separate ListModelLists each with a copy of the elements.

link publish delete flag offensive edit
0

answered 2017-10-24 16:07:56 +0800

MaurizioB gravatar image MaurizioB
3 2

Relation to scrolling: By using a simple ArrayList if you add/remove an element of the list the listbox re-renders the elements sending you to the top of the list (losing the scroll) instead of leaving you where you've added/removed the element.

By reading the documentation this problem is solved by using the ListModel, but unfortunately the sync problem appeared.

I basically need 2+ long lists that retain the screen position when elements are added/removed but do not share the same selection of elements (and save the selected items to 2 different lists). Based on the answers seems that 2+ separated,not live ListModels where I add/remove from each one (and the underlaying list) to mantain them aligned is the solution.

link publish delete flag offensive edit

Comments

now I understand... scrolling itself is not broken (since a scrollbar will always remain) but you wanted to preserve the scroll position when updating the model... for this you definitely have to add single items either through listmodel MVVM or MVC direct component access

cor3000 ( 2017-10-30 14:58:56 +0800 )edit
0

answered 2017-10-30 14:59:16 +0800

cor3000 gravatar image cor3000
6280 2 7

updated 2017-10-30 15:06:22 +0800

Thanks for the clarification.

If memory is a concern you can implement your own ListModel without Selectable:

https://www.zkoss.org/javadoc/latest/zk/org/zkoss/zul/ListModel.html

And take what you need from: https://github.com/zkoss/zk/blob/master/zul/src/org/zkoss/zul/AbstractListModel.java

link publish delete flag offensive edit
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow
1 follower

RSS

Stats

Asked: 2017-10-20 19:16:44 +0800

Seen: 34 times

Last updated: Oct 30 '17

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More