teichmann@5835: package org.dive4elements.river.client.client.widgets; christian@3717: christian@3717: import com.google.gwt.core.client.GWT; christian@3717: import com.google.gwt.i18n.client.NumberFormat; christian@3852: christian@3717: import com.smartgwt.client.data.Record; christian@3717: import com.smartgwt.client.widgets.Button; christian@3717: import com.smartgwt.client.widgets.Label; christian@3717: import com.smartgwt.client.widgets.events.ClickEvent; christian@3717: import com.smartgwt.client.widgets.form.DynamicForm; christian@3717: import com.smartgwt.client.widgets.form.FormItemValueFormatter; christian@3717: import com.smartgwt.client.widgets.form.FormItemValueParser; christian@3717: import com.smartgwt.client.widgets.form.fields.FormItem; christian@3717: import com.smartgwt.client.widgets.form.fields.TextItem; christian@3717: import com.smartgwt.client.widgets.form.fields.events.BlurEvent; christian@3717: import com.smartgwt.client.widgets.form.fields.events.BlurHandler; christian@3717: import com.smartgwt.client.widgets.form.fields.events.KeyPressEvent; christian@3717: import com.smartgwt.client.widgets.form.fields.events.KeyPressHandler; christian@3717: import com.smartgwt.client.widgets.layout.HLayout; christian@3717: teichmann@5835: import org.dive4elements.river.client.shared.model.FacetRecord; christian@3717: christian@3717: import java.util.ArrayList; christian@3717: import java.util.List; christian@3717: christian@3717: /** christian@3717: * SpinnerItem-like element with text label and up/down buttons. christian@3717: */ christian@3717: public class KMSpinner extends HLayout { christian@3717: protected List listeners = new ArrayList(); christian@3717: christian@3717: protected Label label; christian@3717: protected FacetRecord facetRecord; christian@3717: protected double value; christian@3717: christian@3717: public KMSpinner(double initialValue, FacetRecord facetRecord) { christian@3717: super(2); christian@3717: this.facetRecord = facetRecord; christian@3717: this.value = initialValue; christian@3717: christian@3717: setWidth("99%"); christian@3852: setHeight(18); christian@3717: christian@3717: // minusButton shall ask service for previous available cs. christian@3717: Button minusButton = new Button("-"); christian@3717: minusButton.setWidth(18); christian@3717: minusButton.setHeight(18); christian@3717: minusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { christian@3717: public void onClick(ClickEvent evt) { christian@3717: fireChangedEvent(value - 0.1d, false); christian@3717: } christian@3717: }); christian@3717: christian@3717: DynamicForm form = new DynamicForm(); christian@3717: final TextItem kmField = new TextItem(); christian@3717: kmField.setValue(initialValue); christian@3717: kmField.setWidth("*"); christian@3717: kmField.setTitle(""); christian@3717: kmField.setHeight(16); christian@3717: christian@3717: FormItemValueFormatter doubleFormat = new FormItemValueFormatter() { christian@3717: public String formatValue(Object value, Record record, DynamicForm form, FormItem item) { christian@3717: if (value != null) { christian@3717: NumberFormat nf = NumberFormat.getDecimalFormat(); christian@3717: try { christian@3717: double d = Double.valueOf(value.toString()).doubleValue(); christian@3717: return nf.format(d); christian@3717: } christian@3717: catch (Exception e) { christian@3852: GWT.log("EditorValueFormatter exception: " + e.toString()); christian@3852: christian@3852: // Remove junk chars from input string christian@3852: return doublefyString(value.toString()); christian@3717: } christian@3717: } christian@3717: else { christian@3717: return null; christian@3717: } christian@3717: } christian@3717: }; christian@3717: kmField.setEditorValueFormatter(doubleFormat); christian@3717: christian@3717: FormItemValueParser doubleParser = new FormItemValueParser() { christian@3717: public Object parseValue(String value, DynamicForm form, FormItem item) { christian@3717: if (value == null) christian@3717: return null; christian@3717: try { christian@3717: NumberFormat nf = NumberFormat.getDecimalFormat(); christian@3717: double d = nf.parse(value.toString()); christian@3717: return Double.toString(d); christian@3717: } christian@3717: catch(NumberFormatException nfe) { christian@3717: return value; christian@3717: } christian@3717: } christian@3717: }; christian@3717: kmField.setEditorValueParser(doubleParser); christian@3717: christian@3717: // Update on focus lost and enter-pressed. christian@3717: kmField.addBlurHandler(new BlurHandler() { christian@3717: @Override christian@3717: public void onBlur(BlurEvent be) { christian@3717: if (kmField.getValue() != null) { christian@3717: try { christian@3717: fireChangedEvent(Double.parseDouble(kmField.getValue().toString()), true); christian@3717: } christian@3717: catch(NumberFormatException nfe) { christian@3717: GWT.log("entered string cannot be parsed to double."); christian@3717: } christian@3717: } christian@3717: } christian@3717: }); christian@3717: kmField.addKeyPressHandler(new KeyPressHandler() { christian@3717: @Override christian@3717: public void onKeyPress(KeyPressEvent kpe) { christian@3717: if (kpe.getKeyName().equals("Enter")) { christian@3717: kmField.blurItem(); christian@3717: } christian@3717: } christian@3717: }); christian@3717: christian@3717: // TODO: i18n Now add all the validators, formatters, editors/parsers etc. christian@3717: form.setFields(kmField); christian@3717: form.setTitle(""); christian@3717: form.setTitlePrefix(""); christian@3717: form.setTitleSuffix(""); christian@3717: form.setTitleWidth(0); christian@3717: form.setWidth(50); christian@3717: form.setHeight(18); christian@3717: christian@3717: // PlusButton shall ask service for next available cs. christian@3717: Button plusButton = new Button("+"); christian@3717: plusButton.setWidth(18); christian@3717: plusButton.setHeight(18); christian@3717: plusButton.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() { christian@3717: public void onClick(ClickEvent evt) { christian@3717: fireChangedEvent(value + 0.1d, true); christian@3717: } christian@3717: }); christian@3717: christian@3717: this.addMember(minusButton); christian@3717: this.addMember(form); christian@3717: this.addMember(plusButton); christian@3717: } christian@3717: christian@3717: public void addChangeListener(KMSpinnerChangeListener listener) { christian@3717: this.listeners.add(listener); christian@3717: } christian@3717: christian@3717: protected void fireChangedEvent(double val, boolean up) { christian@3717: for(KMSpinnerChangeListener listener : listeners) { christian@3717: listener.spinnerValueEntered(this, val, facetRecord, up); christian@3717: } christian@3717: } christian@3852: christian@3852: /** christian@3852: * Remove junk chars from double string. christian@3852: * This method should work for most locales, but not for christian@3852: * exotic ones that do not use "." or "," as decimal christian@3852: * separator. christian@3852: * @return christian@3852: */ christian@3852: protected String doublefyString(String str) { christian@3852: StringBuilder buf = new StringBuilder(str.length()); christian@3852: christian@3852: for (int n = 0; n < str.length(); n++) { christian@3852: char c = str.charAt(n); christian@3852: if ((c >= '0' && c <= '9') || c == '.' || c == ',') { christian@3852: buf.append(c); christian@3852: } christian@3852: } christian@3852: christian@3852: return buf.toString(); christian@3852: } christian@3717: } christian@3717: