Swing beans binding: how do I notify the target that the model has changed? - swing

I have a swing app with a text box bound to a property on my model (this is a READ_WRITE AutoBinding). The model also has an isDirty property that I want to bind to a button's enabled property.
How do I properly notify the binding when I change the state of isDirty.
Here is my binding code:
BeanProperty<PaChannelConfig, Boolean> paChannelConfigBeanProperty_1 =
BeanProperty.create("dirty");
BeanProperty<JButton, Boolean> jButtonBeanProperty =
BeanProperty.create("enabled");
AutoBinding<PaChannelConfig, Boolean, JButton, Boolean> autoBinding_2 =
Bindings.createAutoBinding(
UpdateStrategy.READ,
model,
paChannelConfigBeanProperty_1,
btnApply, jButtonBeanProperty);
autoBinding_2.bind();
What is the proper way to add this notification?

Basically, the model should have the methods
addPropertyChangeListener(PropertyChangeListener)
removePropertyChangeListener(PropertyChangeListener)
firePropertyChange(PropertyChangeEvent)
look at the class PropertyChangeSupport, that class have implementations of the methods above.
In the model, the method setDirty(boolean) should be implemented like this:
public void setDirty(boolean dirty) {
boolean old = this.dirty;
this.dirty = dirty;
firePropertyChange(new PropertyChangeEvent("dirty", old, dirty));
}
hope that helps

You can use PropertyChangeSupport to easily implement support for property change notification. The documentation at the provided link has an example of how to set it up and use it.

Related

Is there a convention or guideline for mutable state in a Blazor component?

Coming from React JS, I wonder if Blazor has the concepts of State and Property. See the code below:
<div>#field</div>
<button #onclick=#(() => field = Random.Shared.Next())>Change field</button>
<div>#Prop</div>
<button #onclick=#(() => Prop = Random.Shared.Next())>Change prop</button>
#code {
private int field;
[Parameter]
public int Prop { get; set; }
}
There is absolutely no difference between field and Prop, except that you can set Prop from the parent's template. I haven't been able to create a property that cannot be updated within the component, since the public setter is required.
It seems to be up to the team to decide whether it makes sense to update a property within the component or not.
Is there a convention/best practice/guideline about that?
Is there a convention/best practice/guideline about that?
Yes: do no do that.
Most 'official' is in the docs here:
Our general guidance is not to create components that directly write to their own parameters after the component is rendered for the first time.
and here:
Generally, avoid creating components that write directly to their own component parameters. ...
but that is repeated and explained in many places.

Flexsource properties not appearing in rule editor

I followed the demo project here https://codeeffects.com/Doc/Business-Rule-Flex-Source for a sample of how the Flex properties work. My rules are evaluated correctly, but the editor does not show the fields.
I have looked at all of the properties of the FlexPropertyInfo object and confirmed that they set as I would expect. What else should I try in order to troubleshoot this?
Make sure that your Flex type inherits from Type and implements the minimum required properties and methods, and GetProperties in particular, e.g.:
public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
{
List<FlexPropertyInfo> properties = new List<FlexPropertyInfo>();
properties.Add(new FlexPropertyInfo("Id", typeof(int), typeName));
properties.Add(new FlexPropertyInfo("Name", typeof(string), typeName));
return properties.ToArray();
}
Make sure that you pass a new instance of your Flex type and not the type itself.
RuleEditor editor = new RuleEditor("divRuleEditor")
{
Mode = Common.RuleType.Execution,
SourceType = new MyFlexType() //and not typeof(MyFlexType)
}
The Editor itself knows nothing about Flex. As far as it is concerned it is another type and it is using reflection to pull the list of all members. Which is why it is important to pass an instance of your type. Otherwise you will get reflection on the Type class instead. Same goes for properties and other Flex objects.

MvvmCross (iOS) can't bind property in UILabel derived class

MvvmCross noob here. Does anyone know why I can't bind a property in a UILabel derived class?
var set = this.CreateBindingSet<LoginView, LoginViewModel>();
set.Bind(_serverValue).For(p => p.Text).To(vm => vm.ServerListSelectedItem);
set.Bind(_serverValue).For(p => p.Visible).To(vm => vm.IsServerListAvailable);
set.Apply();
private class ServerValue : UILabel
{
public bool Visible
{
get { return !Hidden; }
set { Hidden = !value; LoginView.LayoutControls(); }
}
}
The text gets updated but the Visible property never does. Should I even expect that this should work?
Thanks,
Jon
MvvmCross uses Reflection - and Reflection is subject to .Net security rules.
Try making your control public rather than private to see if that helps -
public class ServerValue : UILabel ...`
Beyond that, there is also a registered custom binding for Visible in MvvmCross by default - see https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Touch/MvxTouchBindingBuilder.cs#L45
registry.RegisterCustomBindingFactory<UIView>("Visible",
view =>
new MvxUIViewVisibleTargetBinding(view));
You may find that this conflicts with (and hides) your Visible property - custom bindings are checked before Reflection - so you may need to choose a different property name.
For more on binding to custom properties and more on custom bindings see N=19 and N=28 in http://mvvmcross.blogspot.com

Jackson 1.9.0: JsonTypeInfo for abstract class not working with Lists

Using this abstract class:
#JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
#JsonSubTypes({ #JsonSubTypes.Type(value = PostingTaskInstanceDto.class, name = "TI") })
public abstract class BasePostingDto {}
and this inherited class:
public class PostingTaskInstanceDto extends BasePostingDto {}
I get correct serialization for a single object. This works, using Spring-MVC:
#RequestMapping("/{id}")
#ResponseBody
public BasePostingDto findById(#PathVariable("id") Long id) {
return createDto(postingService.findById(id));
}
But if I retrieve a List of BasePostingDto from the remote controller, the type property is missing:
#RequestMapping("/by-user/all")
#ResponseBody
public List<BasePostingDto> findByUser() {
return createDtoList(postingService.findByUser(AuthUtils.getUser()));
}
Why is this and how can I force the type property?
Update: the type property is also included if I change List<BasePostingDto> to BasePostingDto[], however I would prefer to go with the List.
It sounds like the framework you are using (and which uses Jackson under the hood) is not passing full generics-aware type information.
I don't know how that can be fixed (it is problem with integration by framework, and not something Jackson can address), but the usual work around is for you to use sub-class of List:
public class PostingDtoList extends List<BasePostingDto> { }
and use that in signature, instead of generic type. This solves the issue because then the generic type signature is retained (since it is stored in super type declaration, and accessible via type-erased PostingDtoList class!).
In generally I think it is best to avoid using generic List and Map types as root type (and instead use POJO); partly because of problems issued (there are bigger problems when using XML for example). But it can be made to work if need be.

Robotlegs wiring up dependencies that belong to a base class

I'm using robot legs, I've got a bunch of ServiceResponses that extends a base class and have a dependency on a Parser, IParser. I need to wire in a parser specific to the subclass. Here's an example:
ModuleConfigResponse extends SimpleServiceResponse and implements IServiceResponse.
The initial part is easy to wire in the context, here's an example:
injector.mapClass(IServiceResponse, ModuleConfigResponse);
injector.mapClass(IServiceResponse, SimpleServiceResponse, "roomconfig");
..etc
Each Response uses a parser that is used by the baseclass:
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
injector.mapValue(IParser, RoomConfigParser, "roomconfig");
The question is how to tie these together. The base class could have:
[Inject]
public var parser : IParser
But I can't define the type ahead of time. Im wondering if there a nice way of wiring this in the context. For the moment I've decided to wire this up by instanciating responses in a ResponseFactory instead so that I pay pass the parser manually in the constructor.
injector.mapValue(IParser, ModuleConfigParser, "moduleconfig");
I realised that not everything can be mapped in the context, RL trapped me into this way of thinking. But I've realised that its far better to map a factory to produce these objects which have very specific dependencies, than littler the codebase with marker interfaces or strings :)
one solution is to have the following in your base class:
protected var _parser : IParser
Then for instance in ModuleConfigResponse
[Inject(name='moduleconfig')]
public function set parser( value : IParser ) : void{
_parser = value;
}
But TBH, using named injections is STRONGLY discouraged, you might as well use a marker interface:
public interface IModuleConfigParser extends IParser{}
the base class stays the same, but ModuleConfigResponse would then use:
[Inject]
public function set parser( value : IModuleConfigParser ) : void{
_parser = value;
}