Hey guys, i’m pretty new to Vaadin and started with vaadin 7.
my goal was, to write an own component wich beheave like an checkbox.
So i used the wiki articles of vaadin 7.
everything went finde till now. i implemented the shared state and the RPC to update the checked true:false value on server side.
it looks like that:
public class sxCheckBox extends AbstractComponent{
private final sxCheckBoxServerRPC srpc = new sxCheckBoxServerRPC() {
@Override
public void clicked(final MouseEventDetails mouseDetails) {
if (getState().enabled) {
getState().checked = !getState().checked;
}
}
};
.................
................
}
Pretty the same as in the example of the vaadin7 wiki.
Now i want to add listeners to my component like in a standard component…
so
final Button btn1 = new Button("test");
btn1.addClickListener(new ClickListener() {
@Override
public void buttonClick(final ClickEvent event) {
cb.setEnabled(!cb.isEnabled());
Notification.show("Checkbox is :"+cb.isEnabled() + " enabled");
}
});
and so on… no problem.
my component should be used similar but there is no methode from superclass to add listeners… sounds normal.
if i want to add a valuechangelistener to my own component, what should i do?
i don’t really know where and how to add a "addValueChangeListener(ValueChangeListener vcl) { … } " method…
it seems that it is easier than expected…i got it with:
HashSet<ValueChangeListener> vcl = new HashSet<ValueChangeListener>();
public void addValueChangeListener(final ValueChangeListener vcl) {
this.vcl.add(vcl);
}
public void removeValueChangeListener(final ValueChangeListener vcl) {
this.vcl.remove(vcl);
}
/**
*
*/
private void updateListeners() {
for (final ValueChangeListener listener : this.vcl) {
listener.valueChange(new ValueChangeEvent() {
@Override
public Property getProperty() {
// TODO Auto-generated method stub
return null;
}
});
}
}
But a last anoying question What is that Property Object and is it a bad style for returning null ?! (mhh i think yes,… returning null is always a bad idea in my thoughts)
But how can it be done better? If the “Property”-thing is fixed , is this the proper way to handle events/listeners on own components?
Maybe you can implement a ValueListenerInterface which would automatically do it but i’m not sure if this works with custom components(
Information ).
What on the other hand should work would be to do some custom event handling:
You should get the click event (
In this article is an example ) then you just need a Listener interface (described
here ). When i find the time i will try to make an example and post it here if not somebody else are quicker or of course you are done before i am.
The Property holds the value that is changed.
Javadoc getProperty() . In a TextField for example it normally holds the text which has changed. For your checkbox you could return the state of the box (true or false).
I don’t have a Vaadin Environment setup right now so i can’t really test it but i think you can do it like this:
public Property getProperty() {
Property property = new Property();
property.setValue(getState().checked);
return property;
}
Property cant be instantiated. its just an interface.
And if i use the generic anonymous iner type of Property i get a bunch of functions that have to be implemented like :
@Override
public T getValue() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setValue(T newValue) throws com.vaadin.data.Property.ReadOnlyException {
// TODO Auto-generated method stub
}
@Override
public Class<? extends T> getType() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isReadOnly() {
// TODO Auto-generated method stub
return false;
}
@Override
public void setReadOnly(boolean newStatus) {
// TODO Auto-generated method stub
}
Oh i think you actually don’t have to instantiate property.
Property property;
property.setValue(...);
but if i’m wrong it’s going to throw a NullPointerException.
Now i have my Environment setup:
If you just want to have a custom listener whose event you can call from your server-side you can do something similar to this:
MyComponent.java:[code]
private MyComponentServerRpc rpc = new MyComponentServerRpc() {
private static final long serialVersionUID = 1L; @Override
public void clicked(MouseEventDetails mouseDetails) {
Iterator i = _listeners.iterator();
while(i.hasNext()) {
Object id = i.next();
((ClickingListener) id).OnClick();
}
}
};
private List<ClickingListener> _listeners = new ArrayList<ClickingListener>();
public synchronized void addEventListener(ClickingListener clickListener){
_listeners.add(clickListener);
}
public synchronized void removeEventListener(ClickingListener clicklistener){
_listeners.remove(clicklistener);
}
public interface ClickingListener extends Serializable{
public void OnClick();
}
[/code]In my case it gets triggered by an rpc.
Usage:[code]
MyComponent testcomp = new MyComponent();
testcomp.addEventListener(new ClickingListener() {
@Override
public void OnClick() {
System.out.println("Clicked");
}
});
[/code]I would also post the rpc but my component crashed my app because of some other change
Built-in Vaadin field components think of values in terms of Properties. Properties are a part of the Vaadin data model library, used to bind data from different sources, such as databases, to Vaadin components.
Property is basically just something that has a value. If you take a look at Vaadin’s own components, you’ll notice that all field components actually
implement the Property interface themselves (via extending AbstractField). Then, they simply return themselves in the getProperty() method - please see Field.ValueChangeEvent.
If you want your own checkbox component to interact nicely with the rest of Vaadin, you should consider implementing Field yourself (you’ll want to do this by extending AbstractField - that way you get lots of handy stuff free, including value change listeners).
Alternatively, you could implement Property yourself; yet another way would be to implement your own ValueChangeListener and ValueChangeEvent interfaces that don’t depend on Properties. These ways, however, would mean lots of reinventing the wheel to create something that does not behave the same way as other Vaadin fields. Of course, it might be a useful learning experience.