I am making a Javafx application and I have a List<String> that I update constantly and I want it to sync with a ListView I have on screen without me needing to update it manually each time. Like binding the ListView by reference. Is this possible? and if so how do I do it? Thanks.
From your question and comments I gather you are trying to do something like:
ObservableList<E> list = ...;
ListView<E> view = ...;
view.itemsProperty().bind(list);
This will not work since bind expects an ObservableValue and ObservableList does not extend that interface. You don't need to bind the items property though. Whatever ObservableList is in the items property will be observed by the ListView for changes (i.e. additions, removals, permutations, and updates1). This means you should be doing something like:
ObservableList<E> list = ...;
ListView<E> view = ...;
view.setItems(list);
And then modifications to list will be reflected in the ListView.
If you need to bind the items property then your ObservableList will either need to be held in an implementation of ObservableValue<ObservableList<E>> or an ObservableListValue<E>.
I recommend reading more about the basics of JavaFX; such as the tutorial on ListView or the documentation.
1. An update change event is fired when a property of an element has been invalidated. In order for an ObservableList to observe the properties of its elements, and thus be capable of firing update events, it must be created with FXCollections.observableArrayList(Callback).
Related
I have a ListView with default lists in the page. I want the list to be replaced with certain conditions to a new list of content in the list view. Somehow I am able to set the list.
The problem is that I need to replace /refresh the listview with new list of items.
How can I accomplish that?
You just need to update the model object: listView.setModelObject(List.of("new", "items")).
If you do this in an Ajax request then you will need to add the listView's parent component to the AjaxRequestTarget: target.add(listView.getParent()). You need to use the parent because repeater components render their markup for each item, so you need to re-render the markup that wraps the items.
I've been searching for that for quite a while and haven't found a proper answer:
Is there a way to remove an Item from a RecyclerView without removing it from the underlying ArrayList?
I want to add a functionality, to temporarily hide Items from the List, when a certain condition is true. I still need those items back later, but managing 2 separate ArrayList seems overly complicated.
If I set the Visibility of the Item inside the Adapter to gone, I have a visible gap where the item was, so that is not a solution.
Is there any way by which I can avoid managing 2 separate ArrayLists?
I think you'll have to actually remove from the data model. Otherwise, you'll either end up with blank rows, as you say, or when you scroll, the "hidden" recycled elements will get jumbled up.
Just because you remove from the the Arraylist doesn't mean you can't add another list to (temporarily) store the items that were removed.
For example, define this in the adapter
private List<Item> removed = new ArrayList<>();
public void remove(int position) {
removed.add(items.get(position));
items.remove(position);
notifyDataSetChanged();
}
If you need better functionality about which items you have removed, a Hashmap may be better.
you have an ArrayList of object type
You have a model/pojo class of Object type
while iterating JsonData from JsonResponse just pass boolean value true/false in object type Model class. The data you want to show make it true else false, later you can set the 'false value to true' to your Model class.
Hope this will work.
In my case, I was using getApplicationContext() instead of getContext or this
I had some issues with a List concept in Codename one. I need a list of items populate dynamically at run time, but I don't know how doing it, so anyone helps me regarding this issue?
Depending on how your list is constructed... E.g. when you have a form with a container, which includes your list as labels.
Container c = new Container(BoxLayout.y());
//adding strings as labels
c.add("String1").add("String2");
Then you can later on add a String to this container
c.add("new String");
But the form won't update itself. So you'd have to
form.revalidate() OR form.animateLayout(150)
to be able to show the changes on the screen.
I have created a class extending JComboBox. the model is set like this:
DefaultComboBoxModel<String> readoutModel = new DefaultComboBoxModel<String>(options.toArray(new String[options.size()]));
setModel(readoutModel);
The class implements a listener interface to listen for changes of another class (myModel). These changes might be not relevant at all for that combobox, it might contain selection changes and it might contain content changes for that combobox.
it's easy to change the selection like this:
#Override
public void modelChanged() {
...
setSelectedItem(myModel.getSelectedReadOut());
}
but what if the content of the combobox needs to be changed? shall I replace the combobox model? would I have to interate over the items and compare them with the items present in myModel? I could also remove all items from the combobox model and then add item by item from myModel? (which would also happen if just the selection changes...).
Three options to update your combo box when the underlying data is changed:
Exchange the model (replace with the new one)
Use a generic mutable model (such as DefaultComboBoxModel) and add/remove the data to reflect the changes
Create your own model implementation which is an Adapter to the actual data, and fire change events to reflect changes on the data.
The Adapter solution is quite easy to implement (ComboBoxModel, which is a ListModel), doesn't need to duplicate data and therefore does not need synchronization. Usually the best option, in my option.
I have created a custom ExpandableListAdapter and everything works properly. What I'd like to be able to do is in each of the groups add a different type of child to the end. I have tried adding 1 to the getChildrenCount() number and then testing isLastChild in the getChildView() method, but that doesn't seem to work.
If a group has three children what I have working looks like this:
Group
NormalChild
NormalChild
NormalChild
But I'd really like something like this:
Group
NormalChild
NormalChild
NormalChild
AlternateChild
The idea being that the AlternateChild could be a link to more info about the group. Any Ideas?
EDIT:
ListView has addFooterView() which will allow you to add a footer to a whole ListView... wonder how to add them to the ExpandableListView's children, or if it's even possible
Perhaps you could try a slightly different approach.
Rather than trying to add an extra item to the ListView directly, maybe try adding an 'AlternateChild' object to the underlying data source using a 'isAlternateChild' flag (or subclassing NormalChild or creating an IChild interface that you extend with NormalChild and AlternateChild.
Then within getChildView you can check to see if the object being displayed within the view is normal or alternate and create or populate the appropriate View-type accordingly.
By adding your extra object to the underlying data/list directly you can let the ExtendedListView do its thing normally. As an added bonus this means you can make the AlternateChild data dynamic and easily make changes to the data displayed in the view by modifying the corresponding object.
In my opinion this is a better answer
I was trying to put an action bar below the last child of each group if needed, this works very nice for that. Since the action bar has nothing to do with my data, I couldn't use the same object.