On maandag 10 april 2017 23:48:27 CEST Pedro Santos wrote: > Hi Emond, > > > Your proposal will not work because Java does not resolve functional > > interfaces to subtypes of the target type. For example, take the Label > > constructor: > I know, and that is just a good thing. Take TextField for example, we don't > want it constructed with a function as a model: > > new TextField("id", Bean::getMethod()) > > this proposal is correctly preventing the user from assigning a read-only > model to a component designed to write on it.
Your solution does not prevent this. Your IReadOnlyModel is a subinterface of IModel. Therefore it is perfectly fine to pass a IReadOnlyModel to the constructor of TextField. In your example, you will need to add a cast or assign it to a variable first: IReadOnlyModel<String> model = Bean::getMethod; new TextField<>("id", model); Also, I think this should be allowed. A disabled TextField provides a read- only view of its model. There are a few read-only usecases in Wicket though: for example ListView and the choices in a dropdown select. > > In Wicket 8 this works, because IModel is a functional interface, so Java > > knows how to convert a method taking no arguments and returning a double > > into a IModel<Double> by mapping that method to getObject(). > > Sure, and it's our job to provide good a API allowing the user to benefit > from Java 8 features *where it does make sense*. A good set of constructors > for a Label would include: > > public Label(String id, IReadyOnlyModel model){ ... } This would require adding additional constructors to all classes that must support read-only models. You cannot replace the constructors, because it is perfectly fine to construct a label with a read-write model. The problem is that the is-a relation for IReadOnlyModel is defined wrongly: a read-write model is a read-only model (a read-write model provides all the capabilities of a read-only model and more). To get this right, IModel needs to be split into 2 super-interfaces: IReadOnlyModel and IWriteOnlyModel, both extending IDetachable. IModel then is simply a combination of IReadOnlyModel and IWriteOnlyModel. Both super-models can be functional interfaces and perhaps we can even support split models on components: new TextField<>("id", Bean::getMethod, Bean::setMethod); The problem however is "default model". For this to work, we need to drop the components default model, because you cannot know if it is IReadOnlyModel, IWriteOnlyModel or IModel. This includes CompoundPropertyModel. But this breaks the API of Wicket bigtime and the gain turned out the be very small. Best regards, Emond