Dynamically Create Menu Items based on an Observable List - java

I have an observable list of type Playlist.
I have a dropdown menu (connected to a MenuButton) with a MenuItem for each item in the list (plus a few default items I hard code that don't change).
For a TableView, I am able to link the data to an ObservableList, and the table's rows automatically update based on the contents of the List.
Is there a way to do the same thing for a MenuButton and its list of MenuItems?

I am not sure if there is built in support but either way, you can write a wrapper for any element you want based off an ObservableList by writing a listener. For example,
public class BoundMenuButton extends MenuButton {
ObservableList<MenuItem> items;
public BoundMenuButton(items) {
super(); // Not sure if needed
this.items = items;
// Listen for changes
items.addListener((ListChangeListener.Change<? extends MenuItem> change) -> {
updateItems();
});
}
public void updateItems() {
Platform.runLater( () -> {
// Do updates
});
}
}
This is just the very basics. You can extend this to have the same methods as a TableView fairly easily. (getItems(), setItems(), etc.).
P.S - This code is untested as I don't have access to a compiler currently.

Related

Eclipse plugin: Properties information not shown correctly when treeview is part of a tabfolder/tabitem

I am developing an eclipse plug in with a tree viewer. Initially I had a single treeview of which I have displayed information of some elements in the standard eclipse properties tab. That worked without problems.
I have followed an example where I implement the IPropertySource and IAdapterFactory. In the method createPartControl() of the view I call
getSite().setSelectionProvider(searchViewer);
which registers the properties.
Now I have added an swt tabfolder item to the plug in. Now In every new tabitem a treeview is displayed. That works fine, but the information in the properties tab are not shown correctly anymore. There's a strange behaviour though. On the tree elements which are of interest I have also added a doubleclick listener to do other things. After I double click an entry and right after single click on another element, the properties are shown for the doubleclicked element?!
I guess the problem is with the SelectionProvider. But I was not able to figure out how to implement it correctly now
The properties view always shows the properties for the object that the selection provider says is the current selection.
If you have multiple tree views on several tabs you will have to write a custom selection provider (ISelectionProvider) that knows which tree is currently active and provides the appropriate selection.
For example, the following is a selection provider used by the JDT code for some things which you could use as a base:
public class SimpleSelectionProvider implements ISelectionProvider {
private final ListenerList<ISelectionChangedListener> fSelectionChangedListeners;
private ISelection fSelection;
public SimpleSelectionProvider() {
fSelectionChangedListeners = new ListenerList<>();
}
#Override
public ISelection getSelection() {
return fSelection;
}
#Override
public void setSelection(ISelection selection) {
fSelection= selection;
for (ISelectionChangedListener listener : fSelectionChangedListeners) {
listener.selectionChanged(new SelectionChangedEvent(this, selection));
}
}
#Override
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
fSelectionChangedListeners.remove(listener);
}
#Override
public void addSelectionChangedListener(ISelectionChangedListener listener) {
fSelectionChangedListeners.add(listener);
}
}
(org.eclipse.jdt.internal.ui.actions.SimpleSelectionProvider)
You would have to make all your trees call the setSelection method when selections change.

JavaFx TableView itemProperty does not notifies ChangeListener

I have problem with my TableView element. I adding listener like that:
HardwareIdTableView.getItems().addListener(
(ListChangeListener.Change<? extends FirmwareData.HardwareIdWrapper> change) -> {
checker.hardwareIdCompleted.setValue(change.getList().size() > 0);
});
checker.hardwareIdCompleted is BooleanProperty.
I checked in debugger and new items was added to the TableView, but hardwareIdCompleted still resist 'false'.
P.S.
I add items to TableView like this:
public void addHardwareKey(HardwareIdKeyT key) {
ObservableList<FirmwareData.HardwareIdWrapper> idKeys = HardwareIdTableView.getItems();
if (idKeyEditSelected != null) {
fwData.removeHardwareIdKey(idKeyEditSelected.getIdPattern());
idKeys.remove(idKeyEditSelected);
}
if (!idKeys.contains(key)) {
HardwareIdTitledPane.pseudoClassStateChanged(PseudoClass.getPseudoClass("pane-error"), false);
idKeys.add(new FirmwareData.HardwareIdWrapper(key));
fwData.addHardwareIdKey(key);
}
}
The fault was straight - my reset function assigned new list to TableView. Since listener was assigned to old item list, it doesn't get notification, when I was expecting.

Refresh Listview javafx with attached listener in javafx

I have a list view that is populated by an observable Array list. My steps are the following
Populate observable array list
Populate list view using listView.setItems() method
set custom cell using listView.setCellFactory(),
Attach listener for list view.
More particularly attachListener happens this way
private void attachListViewListener() {
testServersListView.getSelectionModel().selectedItemProperty().addListener((ObservableValue <? extends TestserverInformation> ov, TestserverInformation oldValue, TestserverInformation newValue )->{
this.selectedInfo = testServersListView.getSelectionModel().getSelectedItem();
updateTabs();
});
}
I want to be able to refesh the list by pushing a button. The methods are the following
#FXML
public void btnRefreshServerListClicked(){
log.info("Refreshing list");
testServersListView.getItems().clear();
fillObservableTestserverInfoList();
testServersListView.setItems(observableTestserverInfoList);
selectAndUpdate(); //selects the first element on the list
}
The problem is that when I clear the list items selectedInfo variable is set to null and the Listener is tiggered, causing a nullpointerexception (because selectAndUpdate uses selectedInfo for updating it's controls. Can I remove the listener without having to set it as a different variable e.g?
private myListener = new ChangeListener<...>(){
};

Items changed event for JavaFX ListView control

I am looking for something like an Item Changed Event or Item Count Changed Event for JavaFX ListView control or lets just say in general for any collection type control.
It is because, I have some Buttons, that I want to be enabled only when there is at least one item in ListView otherwise that Button should be in disabled state.
It is my guess that perhaps adding a ChangeListener to the ListView control. would that be a right approach.
Any suggestions how can we achieve this.
The JavaFX Listview provides a method with the signature
public final ObservableList<T> getItems()
You can add a listener to the observable list which will be called whenever items are added to or removed from the ListView.
aListView.getItems().addListener(new ListChangeListener() {
#Override
public void onChanged(ListChangeListener.Change change) {
System.out.println("Detected a change! ");
}
});
Similar functionality is also provided by the other 'collection' controls.
Add a binding based on the ListView items using Bindings.isEmpty
button.disableProperty().bind(Bindings.isEmpty(listView.getItems()));
This will also work when someone calls ListView#setItems and completely changes the observable list:
InvalidationListener updateScrollBarListener = ...
aListView.itemsProperty().addListener((obs, old, current) -> {
if(old != null) {
old.removeListener(updateScrollBarListener);
}
if(current != null) {
current.addListener(updateScrollBarListener);
}
});
I've been looking for a way to to make this a bit shorter (perhaps with Bindings) but haven't found it so far.

How to respond to click on a table row in vaadin

I've got the following code:
public Button getBtnSubmit(com.vaadin.ui.Button.ClickListener l) {
if (null != l) {
btnSubmit.addListener(l);
}
return btnSubmit;
}
public Table getTableCompany(HeaderClickListener hl) {
if (null != hl) {
tableCompany.addListener(hl);
}
return tableCompany;
}
I would like to add a listener that fires when I select a (different) row in the table.
This so that I can refresh some other controls with the table data, which listener should I use?
addListener is deprecated now. Use the following instead.
table.addItemClickListener(new ItemClickEvent.ItemClickListener() {
#Override
public void itemClick(ItemClickEvent itemClickEvent) {
System.out.println(itemClickEvent.getItemId().toString());
}
});
I would go for ItemClickListener:
table.addListener(new ItemClickEvent.ItemClickListener() {
#Override
public void itemClick(ItemClickEvent event) {
//implement your logic here
}
});
edit: For Vaadin 7+, use addItemClickListener method instead of addListener.
You want to add a ValueChangeListener
If you use the ValueChangeListener don't forget to set
table.setImmediate(true);
This means that the browser will report a change on selection immediately. If you don't set this your listener is not called.
Read https://vaadin.com/book/-/page/components.table.html, section 5.15.1 "Selecting Items in a Table". You want to add a Property.ValueChangeListener.
Many of these answers are both correct, and incorrect.
If you need to get the selected items in response to the click, register a ValueChangeListener. Calling getValue() to retrieve the selection from the ItemClickListener might be 1 item behind in a MultiSelect list. For example, the set of items won't include/exclude the item triggering the callback. You will not have a reference to the clicked item however.
If you simply want to respond to a click on an item, and do not need to consider the current selection state, register an ItemClickListener instead. This way you will know what item was actually clicked.

Categories