How to invalidate a component?

I have a widget that extends a Vaadin layout, with a bunch of properties and a paint routine

class MyWidgetImpl extends CssLayout {
 
  // Internal state. Setters/Getters provided
  private int rows;
  private int columns;
  private int color;

  public void paint() {
    // ... paint code here: create layouts, add widgets, query services etc
  }
}

I have two choices:

  1. Call paint() after each setters is invoke. Downside: when setting N properties, N - 1 calls are wasted
  2. Require client code to call paint() after all the status updates. Downside: paint() calls everywhere…

What is the standard way to invalidate a component so that the framework will call the paint routine before sending the response to the client? I saw markAsDirty(), but can’t find the callback to override in my widget

Hi,

I don’t exactly know what you are trying to accomplish. Normally, you build a composite component just once, typically in the constructor, and then just modify it as is necessary. Sometimes it’s easiest to rebuild the content, but rarely.

The framework doesn’t call a “paint()” method. There was a paintContent() method in Vaadin 6, but it was for low-level serialization to the client-side, which is completely different level from what you are doing there. Also markAsDirty() works at lower level than what you are probably trying to do.

Hi Marko,

for my component I found it easier to rebuild the whole hierarchy instead of updating existing components in place. Other toolkits have a rendering loop you can hook into, but from your answer I guess Vaadin has not, so I’m sticked with the two options listed in the original post.

I was trying to avoid needless calls to the paint routine because, given the current implementation, it queries an external service and it’s expensive to invoke. Imagine clients like this:

public void onSomeEvent() {
  widget.setRows(x);
}

public void onAnotherEvent() {
  widget.setRows(x);
  widget.setColumns(y);
}

public void onYetAnotherEvent() {
  widget.setColumns(y);
  widget.setSomeFlag(false);
  widget.setAnotherFlag(true);
  widget.setColor(RED);
}

You see where we’re going. Ideally all these use-cases should lead to only one paint() call in the widget implementation, because making four in a row wastes the first three ones. Sure I can work on my API and/or the widget implementation to optimize the slow points, but it would have been useful if, inside my setters, I could have told to the framework “Hey, when you are about to respond, call the paint() method” and the framework would have invoked the callback before sending the response to the client.

Is there a good reason why you need to rebuild the composite component every time any of its properties changes? That is very far from the normal way of developing Vaadin applications and I still can’t see why you would want to do so.

I think there’s a misunderstanding, so let’s try to simplify things. Imagine I have only one property in my widget:

public class MyWidget {
  private int numberOfRows; // setters and getters provided
}

Every time setNumberOfRows(N) is called, i remove all rows from the layout, then build and add N rows. Now suppose that the processing of a single event results in the following:

... event is received ...
setNumberOfRows(5);
....
setNumberOfRows(18);
...
setNumberOfRows(7);
... ok, we're done now ....

I don’t think it’s unusual to throttle calls so that the widget is repainted only one time, with 7 rows. Again, I could modify my code to proxy the settings to another object and drawing with the eventual value - or I could explicitely call the paint routine when I know the transaction has ended (whic seems the way you suggest, and requires a call to repaint() when you’re done)

Both of the approaches are cumbersome and have their downsides (already listed in another post) so I hoped there existed a way to collaborate with the framework, but there isn’t. Not that I’m shocked, but is a model that every toolkit library out there provides: you mark dirty regions and the framework calls you back when rendering the frame. I understand that maybe Vaadin doesn’t expose this hook at the application level, but it’s far from an unusual request and there’s really nothing wrong with the code.

Sorry, I still don’t completely understand what you are after. Maybe you are trying to simplify things too much - I see just a fraction of the code and don’t quite see why you are doing it that way. Your question is just too abstract.

For example, I don’t know what the “rows” here are and why you would need to modify them back and forth during the processing of an event. If the rows are components inside the layout, just add and remove them - you don’t need to rebuild (“repaint”) the layout.

But sure, if rebuilding is more efficient than modifying, then call a “repaint()” method in the end, as you suggested. If you are annoyed about having such repaint methods at the end of every event handler, just wrap the event handlers inside something that calls the repaint.

I don’t know how what sort of events you have and how you are handling them, but you could have a wrapper such as the following:[code]
class MyWidgetImpl extends CssLayout {
abstract class MyListenerWrapper implements ClickListener {
public void click(Event e) {
wasClicked(e);
paint();
}

     public void wasClicked(Event e);
}

MyWidgetImpl() {
    ...
    Button button = ...
    button.addClickListener(new MyListenerWrapper() {
        wasClicked(Event e) {
            setNumberOfRows(getNumberOfRows()+1); // Or whatever
            setNumberOfCols(5); // Or whatever
        }
    });
}

private void paint() {
//…
}
}

[/code]