I have a ListView full of POJOs and want a label in the GUI to display informations from the selected item.
My POJO looks something like that:
class Customer {
private String name;
...
public String getName() {
return name;
}
Now when the user selects a customer from the list I want the name of the selected customer displayed in a label.
Obviously I can't bind to the name
directly because it is not a Property
. (And I don't want to replace my Customers String
s with StringProperty
-objects because the SimpleStringProperty
is not serializable
and I need the Customer
to be transfered via RMI.)
I've tried the BeanPathAdapter
from JFXtras (which looks really nice by the way) like this:
BeanPathAdapter<MultipleSelectionModel> customerBeanPathAdapter;
customerBeanPathAdapter = new BeanPathAdapter<>(lstCustomers.getSelectionModel());
customerBeanPathAdapter.bindBidirectional("selectedItem.name", lblCustomerName.textProperty());
But this solution only throws me an Exception:
...
Caused by: java.lang.IllegalArgumentException: Unable to resolve accessor getSelectedItem
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3062)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessorWithLikelyPrefixes(BeanPathAdapter.java:3022)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.updateMethodHandles(BeanPathAdapter.java:2986)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.<init>(BeanPathAdapter.java:2977)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1348)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldBean.performOperation(BeanPathAdapter.java:1186)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:567)
at jfxtras.labs.scene.control.BeanPathAdapter.bindBidirectional(BeanPathAdapter.java:369)
at at.gs1.sync.qm.client.gui.MainWindowController.initialize(MainWindowController.java:61)
... 22 more
Caused by: java.lang.IllegalAccessException: symbolic reference class is not public: class javafx.scene.control.ListView$ListViewBitSetSelectionModel, from jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle
at java.lang.invoke.MemberName.makeAccessException(MemberName.java:512)
at java.lang.invoke.MethodHandles$Lookup.checkSymbolicClass(MethodHandles.java:1113)
at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1094)
at java.lang.invoke.MethodHandles$Lookup.findVirtual(MethodHandles.java:626)
at jfxtras.labs.scene.control.BeanPathAdapter$FieldHandle.buildAccessor(BeanPathAdapter.java:3049)
... 30 more
So I hoped there would be a better solution than to use lstCustomers.getSelectionModel().selectedItemProperty().addListener(...)
and handle the population of the labels there manually.
A better solution I think, to the one I gave before, is to use the BeanPathAdapter as you tried.
However the BeanPathAdapter needs to have the following property added to it:
private final ObjectProperty<B> beanProp = new SimpleObjectProperty<>();
{
beanProp.addListener( new ChangeListener<B>()
{
@Override
public void changed( ObservableValue<? extends B> ob, B oldVal, B newVal )
{
setBean( newVal );
}
} );
}
public ObjectProperty<B> beanProperty()
{
return beanProp;
}
Then in your code you need the following:
BeanPathAdapter<Customer> custBean;
custBean = new BeanPathAdapter<>( new Customer() ); // empty or any customer
custBean.bindBidirectional( "name", label.textProperty() );
custBean.beanProperty().bind( listview.getSelectionModel().selectedItemProperty() );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With