Java tutorial
/** * Exhibit A - UIRF Open-source Based Public Software License. * * The contents of this file are subject to the UIRF Open-source Based Public * Software License(the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * openelis.uhl.uiowa.edu * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is OpenELIS code. * * The Initial Developer of the Original Code is The University of Iowa. * Portions created by The University of Iowa are Copyright 2006-2008. All * Rights Reserved. * * Contributor(s): ______________________________________. * * Alternatively, the contents of this file marked "Separately-Licensed" may be * used under the terms of a UIRF Software license ("UIRF Software License"), in * which case the provisions of a UIRF Software License are applicable instead * of those above. */ package org.openelis.ui.widget; import java.util.ArrayList; import org.openelis.ui.widget.EditBox; import org.openelis.ui.common.Exceptions; import org.openelis.ui.common.Util; import org.openelis.ui.common.data.QueryData; import com.google.gwt.event.dom.client.BlurEvent; import com.google.gwt.event.dom.client.BlurHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.FocusEvent; import com.google.gwt.event.dom.client.FocusHandler; import com.google.gwt.event.dom.client.HasBlurHandlers; import com.google.gwt.event.dom.client.HasFocusHandlers; import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.event.dom.client.KeyDownHandler; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.dom.client.MouseDownEvent; import com.google.gwt.event.dom.client.MouseDownHandler; import com.google.gwt.event.dom.client.MouseOutEvent; import com.google.gwt.event.dom.client.MouseOutHandler; import com.google.gwt.event.dom.client.MouseOverEvent; import com.google.gwt.event.dom.client.MouseOverHandler; import com.google.gwt.event.logical.shared.CloseEvent; import com.google.gwt.event.logical.shared.CloseHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.HasValue; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment; public class EditBox extends Composite implements ScreenWidgetInt, Queryable, Focusable, HasBlurHandlers, HasFocusHandlers, HasValue<String>, HasHelper<String>, HasExceptions { /** * Used for EditBox display */ protected Grid display; protected Button button; protected PopupPanel popup; protected TextArea ta; protected boolean required, showing, queryMode; protected int maxLength; protected TextBase textbox; protected String value; protected EditBox source = this; protected WidgetHelper<String> helper = new StringHelper(); /** * Exceptions list */ protected Exceptions exceptions; /** * Default no-arg constructor */ public EditBox() { init(); } public void init() { display = new Grid(1, 2); display.setCellSpacing(0); display.setCellPadding(0); textbox = new TextBase(); button = new Button(null, "..."); display.setWidget(0, 0, textbox); display.setWidget(0, 1, button); initWidget(display); display.setStyleName("SelectBox"); textbox.setStyleName("TextboxUnselected"); /* * Set the focus style when the Focus event is fired Externally */ addFocusHandler(new FocusHandler() { public void onFocus(FocusEvent event) { if (isEnabled()) { display.addStyleName("Focus"); selectAll(); } } }); /* * Removes the focus style when the Blue event is fires externally */ addBlurHandler(new BlurHandler() { public void onBlur(BlurEvent event) { display.removeStyleName("Focus"); unselectAll(); finishEditing(); } }); /* * Since HorizontalPanel is not a Focusable widget we need to listen to * the textbox focus and blur events and pass them through to the * handlers registered to source. */ textbox.addFocusHandler(new FocusHandler() { public void onFocus(FocusEvent event) { FocusEvent.fireNativeEvent(event.getNativeEvent(), source); } }); textbox.addBlurHandler(new BlurHandler() { public void onBlur(BlurEvent event) { if (!showing && isEnabled()) BlurEvent.fireNativeEvent(event.getNativeEvent(), source); } }); button.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { showPopup(); } }); button.addMouseDownHandler(new MouseDownHandler() { public void onMouseDown(MouseDownEvent event) { showing = true; } }); exceptions = new Exceptions(); } private void showPopup() { showing = true; if (popup == null) { popup = new PopupPanel(true); popup.setPreviewingAllNativeEvents(false); popup.addCloseHandler(new CloseHandler<PopupPanel>() { public void onClose(CloseEvent<PopupPanel> event) { setValue(ta.getText(), true); showing = false; } }); ta = new TextArea(); ta.setWidth("300px"); ta.setStyleName("ScreenTextArea"); ta.addKeyDownHandler(new KeyDownHandler() { @Override public void onKeyDown(KeyDownEvent event) { switch (event.getNativeKeyCode()) { case KeyCodes.KEY_TAB: popup.hide(); setFocus(true); KeyDownEvent.fireNativeEvent(event.getNativeEvent(), source); break; case KeyCodes.KEY_ENTER: popup.hide(); setFocus(true); break; } } }); popup.setWidget(ta); popup.setStyleName("DropdownPopup"); } ta.setText(textbox.getText()); popup.showRelativeTo(this); ta.setFocus(true); ta.selectAll(); } @Override public String getValue() { return value; } @Override public void setValue(String value) { setValue(value, false); } @Override public void setValue(String value, boolean fireEvents) { if (!Util.isDifferent(this.value, value)) { if (value != null) textbox.setText(helper.format(value)); return; } this.value = value; if (value != null) { textbox.setText(helper.format(value)); } else { textbox.setText(""); } if (fireEvents) ValueChangeEvent.fire(this, value); } /** * This method will call the Helper to get the T value from the entered * string input. if invalid input is entered, Helper is expected to throw an * en exception and that exception will be added to the validate exceptions * list. * * @param fireEvents */ public void finishEditing() { String text; if (isEnabled()) { if (queryMode) validateQuery(); else { text = textbox.getText(); if (textbox.enforceMask && textbox.picture.equals(text)) { text = ""; textbox.setText(""); } clearValidateExceptions(); try { setValue(helper.getValue(text), true); if (required && value == null) addValidateException(new Exception("exc.fieldRequiredException")); } catch (Exception e) { addValidateException(e); } Balloon.checkExceptionHandlers(this); } } } /** * Method used to validate the inputed query string by the user. */ public void validateQuery() { try { clearValidateExceptions(); helper.validateQuery(textbox.getText()); } catch (Exception e) { addValidateException(e); } Balloon.checkExceptionHandlers(this); } // ******** Implementation of Queryable ***************** /** * This method will toggle TextBox into and from query mode and suspend or * resume any format restrictions */ public void setQueryMode(boolean query) { if (queryMode == query) { return; } if (query) { queryMode = true; textbox.enforceMask = false; textbox.setMaxLength(255); textbox.setAlignment(TextAlignment.LEFT); } else { queryMode = false; textbox.enforceMask = true; textbox.setMaxLength(maxLength); textbox.setAlignment(TextAlignment.LEFT); textbox.setText(""); } } /** * Returns a single QueryData object representing the query string entered * by the user. The Helper class is used here to create the correct * QueryData object for the passed type T. */ public Object getQuery() { Object query; query = helper.getQuery(textbox.getText()); return query; } /** * Sets a query string to this widget when loaded from a table model */ public void setQuery(QueryData qd) { if (qd != null) textbox.setText(qd.getQuery()); else textbox.setText(""); } /** * Method used to determine if widget is currently in Query mode */ public boolean isQueryMode() { return queryMode; } // ********** Implementation of HasException interface *************** /** * Convenience method to check if a widget has exceptions so we do not need * to go through the cost of merging the logical and validation exceptions * in the getExceptions method. * * @return */ public boolean hasExceptions() { if (getValidateExceptions() != null) return true; if (required && getValue() == null) { addValidateException(new Exception("exc.fieldRequiredException")); Balloon.checkExceptionHandlers(this); } return getEndUserExceptions() != null || getValidateExceptions() != null; } /** * Adds a manual Exception to the widgets exception list. */ public void addException(Exception error) { exceptions.addException(error); Balloon.checkExceptionHandlers(this); } protected void addValidateException(Exception error) { exceptions.addValidateException(error); } /** * Combines both exceptions list into a single list to be displayed on the * screen. */ public ArrayList<Exception> getValidateExceptions() { return exceptions.getValidateExceptions(); } public ArrayList<Exception> getEndUserExceptions() { return exceptions.getEndUserExceptions(); } /** * Clears all manual and validate exceptions from the widget. */ public void clearExceptions() { exceptions.clearExceptions(); removeExceptionStyle(); Balloon.clearExceptionHandlers(this); } public void clearEndUserExceptions() { exceptions.clearEndUserExceptions(); Balloon.checkExceptionHandlers(this); } public void clearValidateExceptions() { exceptions.clearValidateExceptions(); Balloon.checkExceptionHandlers(this); } /** * Will add the style to the widget. */ public void addExceptionStyle() { if (Balloon.isWarning(this)) addStyleName("InputWarning"); else addStyleName("InputError"); } /** * will remove the style from the widget */ public void removeExceptionStyle() { removeStyleName("InputError"); removeStyleName("InputWarning"); } // ************* Implementation of Focusable ****************** /** * Method only implemented to satisfy Focusable interface. */ public int getTabIndex() { return -1; } /** * Method only implemented to satisfy Focusable interface. */ public void setTabIndex(int index) { } /** * Method only implemented to satisfy Focusable interface. */ public void setAccessKey(char key) { } /** * Exposing this method on the wrapped widget */ public void selectAll() { textbox.selectAll(); } /** * Exposing this method on the wrapped widget */ public void setSelectionRange(int pos, int length) { textbox.setSelectionRange(pos, length); } /** * Exposing this method on the wrapped widget */ public void unselectAll() { textbox.setSelectionRange(0, 0); } public void setMask(String mask) { textbox.setMask(mask); } /** * This is need for Focusable interface and to allow programmatic setting of * focus to this widget. We use the wrapped TextBox to make this work. */ public void setFocus(boolean focused) { textbox.setFocus(true); } // ************ Handler Registration methods ********************* /** * The Screen will add its screenHandler here to register for the * onValueChangeEvent */ public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) { return addHandler(handler, ValueChangeEvent.getType()); } /** * This Method is here so the Focus logic of ScreenPanel can be notified */ public HandlerRegistration addBlurHandler(BlurHandler handler) { return addHandler(handler, BlurEvent.getType()); } /** * This method is here so the Focus logic of ScreenPanel can be notified */ public HandlerRegistration addFocusHandler(FocusHandler handler) { return addHandler(handler, FocusEvent.getType()); } /** * Adds a mouseover handler to the textbox for displaying Exceptions */ public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) { return addDomHandler(handler, MouseOverEvent.getType()); } /** * Adds a MouseOut handler for hiding exceptions display */ public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) { return addDomHandler(handler, MouseOutEvent.getType()); } public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) { return addDomHandler(handler, KeyUpEvent.getType()); } /** * Overridden method from TextBox for enabling and disabling the widget */ @Override public void setEnabled(boolean enabled) { button.setEnabled(enabled); textbox.setReadOnly(!enabled); if (enabled) sinkEvents(Event.ONKEYDOWN | Event.ONKEYUP); else unsinkEvents(Event.ONKEYDOWN | Event.ONKEYUP); } @Override public boolean isEnabled() { return !textbox.isReadOnly(); } @Override public void setHelper(WidgetHelper<String> helper) { this.helper = helper; } @Override public WidgetHelper<String> getHelper() { return helper; } public void setRequired(boolean required) { this.required = required; } public void setMaxLength(int max) { this.maxLength = max; textbox.setMaxLength(max); } public void setCase(TextBase.Case textCase) { textbox.setCase(textCase); } }