The question is simple, remember FormButtonBinding, it used to work on a FormPanel (GXT 2.x). The logic is to use a Timer and call a validate function. I am trying to achieve the same using EditorDriver. I have created a simple bean editor and invoked driver. I am able to set the violations on the form fields. However, due to repetitive calls from the server, the error message and icon flicker. How do I achieve this without flicker issues.
Edit: Incase it is not clear, isValidModel() method is used to trigger this. I have not pasted the presenter and view to reduce SPAM
Driver code:
Code:
public class RegistrationDetailViewDriver implements HasPreventiveValidation {
interface Driver extends SimpleBeanEditorDriver<TransactionDetail, RegistrationDetailView> {
}
Driver driver = GWT.create(Driver.class);
private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
public RegistrationDetailView edit(TransactionDetail regDetails) {
RegistrationDetailView editor = BpmUIInjector.INSTANCE.getRegistrationDetailView();
driver.initialize(editor);
driver.edit(regDetails);
return editor;
}
public TransactionDetail save() {
Window.alert("test alert");
TransactionDetail details = driver.flush();
return details;
}
/* (non-Javadoc)
* @see com.xxx.tps.bpm.ui.client.shared.driver.HasPreventiveValidtion#isValidModel()
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public boolean isValidModel() {
TransactionDetail transactionDetail = driver.flush();
Set<ConstraintViolation<TransactionDetail>> violations = validator.validate(transactionDetail);
boolean valid = violations.isEmpty();
if(needToChangeView(violations)){
driver.setConstraintViolations((Set)violations);
}
return valid;
}
Set<String> oldViolations = new HashSet<String>(4);
private boolean needToChangeView(Set<ConstraintViolation<TransactionDetail>> violations) {
boolean onlyOldErrors = true;
Set<String> newViolations = new HashSet<String>(4);
for (ConstraintViolation<TransactionDetail> constraintViolation : violations) {
String key = constraintViolation.getPropertyPath()+"_|_"
+constraintViolation.getInvalidValue()+"_|_"
+constraintViolation.getMessage()+"_|_"
+constraintViolation.getRootBean().toString();
onlyOldErrors = onlyOldErrors && oldViolations.contains(key);
newViolations.add(key);
}
boolean mismatch = oldViolations.size() != newViolations.size();
oldViolations = newViolations;
return !onlyOldErrors || mismatch;
}
}
and FormButtonBinding code
Code:
/**
* Monitors the valid state of a form and enabled / disabled all buttons.
*/
public class FormButtonBinding {
private HasPreventiveValidation validator;
private Widget panel;
private Timer timer;
private int interval = 500;
private Handler listener;
private List<TextButton> buttons;
public FormButtonBinding(HasPreventiveValidation validator, Widget panel) {
this.validator = validator;
this.panel = panel;
buttons = new ArrayList<TextButton>();
timer = new Timer() {
@Override
public void run() {
FormButtonBinding.this.checkPanel();
}
};
listener = new Handler() {
@Override
public void onAttachOrDetach(AttachEvent event) {
if (event.isAttached()) {
FormButtonBinding.this.startMonitoring();
} else {
FormButtonBinding.this.stopMonitoring();
}
}
};
panel.addAttachHandler(listener);
if (panel.isAttached()) {
startMonitoring();
}
}
public void addButton(TextButton button) {
buttons.add(button);
}
public int getInterval() {
return interval;
}
public void removeButton(TextButton button) {
buttons.remove(button);
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startMonitoring() {
if (panel.isAttached()) {
timer.run();
timer.scheduleRepeating(interval);
}
}
public void stopMonitoring() {
timer.cancel();
}
protected boolean checkPanel() {
if(validator == null){
return true;
}
boolean v = validator.isValidModel();
for (TextButton button : buttons) {
if (v != button.isEnabled()) {
button.setEnabled(v);
}
}
return v;
}
}