Java tutorial
/* * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt */ package edu.caltech.ipac.firefly.ui; import com.google.gwt.dom.client.Style; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.DockLayoutPanel; import com.google.gwt.user.client.ui.DockPanel; import com.google.gwt.user.client.ui.HasHorizontalAlignment; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.RequiresResize; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import edu.caltech.ipac.firefly.core.Application; import edu.caltech.ipac.firefly.core.HelpManager; import edu.caltech.ipac.firefly.util.WebClassProperties; import edu.caltech.ipac.firefly.util.event.Name; import edu.caltech.ipac.firefly.util.event.WebEvent; import edu.caltech.ipac.firefly.util.event.WebEventListener; import edu.caltech.ipac.firefly.util.event.WebEventManager; import edu.caltech.ipac.util.dd.ValidationException; import java.util.ArrayList; import java.util.List; /** * User: roby * Date: Oct 29, 2008 * Time: 9:47:20 AM */ /** * @author Trey Roby */ public abstract class BaseDialog { public enum ButtonID { NO_BUTTON, OK, APPLY, CANCEL, HELP, REMOVE, YES, NO, USER } public enum HideType { BEFORE_COMPLETE, AFTER_COMPLETE, DONT_HIDE } public static final int BUTTON_HEIGHT = 20; private static WebClassProperties _prop = new WebClassProperties(BaseDialog.class); private final static String CANCEL_TXT = _prop.getName("cancel"); private final static String OK_TXT = _prop.getName("ok"); private final static String APPLY_TXT = _prop.getName("apply"); private final static String REMOVE_TXT = _prop.getName("remove"); private final static String HELP_TXT = _prop.getName("help"); private final static String YES_TXT = _prop.getName("yes"); private final static String NO_TXT = _prop.getName("no"); private final PopupPane _popup; private HorizontalPanel _buttons = new HorizontalPanel(); private ButtonType _type; private Widget _theWidget = null; private HideType _hideAlgorithm = HideType.BEFORE_COMPLETE; private final Widget _parent; private boolean _firstTime = true; private final List<ClickHandler> _clickList = new ArrayList<ClickHandler>(3); private final String _helpID; private boolean _sizeSet = false; //====================================================================== //----------------------- Constructors --------------------------------- //====================================================================== public BaseDialog(Widget parent, ButtonType type, String title) { this(parent, type, PopupType.STANDARD, title, false, false, null); } public BaseDialog(Widget parent, ButtonType type, String title, String helpID) { this(parent, type, PopupType.STANDARD, title, false, false, helpID); } public BaseDialog(Widget parent, ButtonType type, String title, boolean modal, String helpID) { this(parent, type, PopupType.STANDARD, title, modal, false, helpID); } public BaseDialog(Widget parent, ButtonType type, PopupType ptype, String title, boolean modal, boolean autoHide, String helpID) { _parent = parent; _type = type; _helpID = helpID; _popup = new DialogPopupPane(title, null, ptype, modal, autoHide); _popup.getPopupPanel().addStyleName("base-dialog"); buildDialog(); WebEventManager.getAppEvManager().addListener(Name.REGION_CHANGE, new WebEventListener() { public void eventNotify(WebEvent ev) { if (isVisible() && _popup.isDoRegionChangeHide()) doCancel(); } }); } //====================================================================== //----------------------- Public Methods ------------------------------- //====================================================================== public void setAnimationEnabled(boolean animation) { _popup.setAnimationEnabled(animation); } public void setButtonText(ButtonID button, String text) { Button b = getButton(button); if (b != null) b.setText(text); } public Button getButton(ButtonID button) { Button b = null; for (Widget w : _buttons) { if (w instanceof DialogButton) { if (((DialogButton) w).getID() == button) { b = (DialogButton) w; break; } } } return b; } public void setWidget(Widget w) { _theWidget = w; if (w instanceof RequiresResize) { DockLayoutPanel contents = new DockLayoutPanel(Style.Unit.PX); DockLayoutPanel layout = new DockLayoutPanel(Style.Unit.PX); _popup.setWidget(layout); VerticalPanel vp = new VerticalPanel(); vp.add(_buttons); vp.setWidth("100%"); layout.addSouth(vp, 50); layout.add(contents); contents.addStyleName("base-dialog"); contents.addStyleName("base-dialog-contents"); contents.add(w); } else { SimplePanel contents = new SimplePanel(); DockPanel layout = new DockPanel(); _popup.setWidget(layout); layout.add(_buttons, DockPanel.SOUTH); layout.add(contents, DockPanel.CENTER); contents.addStyleName("base-dialog"); contents.addStyleName("base-dialog-contents"); contents.setWidget(w); } } public Widget getWidget() { return _theWidget; } public void addButton(Button b) { Button helpButton = getButton(ButtonID.HELP); if (helpButton != null) { int idx = _buttons.getWidgetIndex(helpButton); _buttons.insert(b, idx); } else { _buttons.add(b); } } public void addButtonAreaWidget(Widget w) { _buttons.add(w); } public void addButtonAreaWidgetBefore(Widget w) { _buttons.insert(w, 0); } public boolean isVisible() { return _popup.isVisible(); } public void setDoRegionChangeHide(boolean doHide) { _popup.setDoRegionChangeHide(doHide); } public void setVisible(boolean visible) { setVisible(visible, null, Integer.MIN_VALUE, Integer.MAX_VALUE); } public void setVisible(boolean visible, PopupPane.Align alignAt) { setVisible(visible, alignAt, Integer.MIN_VALUE, Integer.MAX_VALUE); } public void setVisible(boolean visible, PopupPane.Align alignAt, int xOffset, int yOffset) { if (_firstTime && visible) deferredBuild(); setContainerVisible(visible, alignAt, xOffset, yOffset); if (visible) { final boolean first = _firstTime; DeferredCommand.addCommand(new Command() { public void execute() { if (first) { onFirstVisible(); if (_theWidget instanceof RequiresResize && !_sizeSet) { int maxW = Math.max(_theWidget.getOffsetHeight(), _buttons.getOffsetHeight()); setDefaultContentSize(maxW, _theWidget.getOffsetHeight() + _buttons.getOffsetHeight()); } } onVisible(); } }); _firstTime = false; } } public void show() { show(0, PopupPane.Align.CENTER); } public void show(int autoCloseSecs, PopupPane.Align alignAt) { setVisible(true, alignAt); if (autoCloseSecs > 0) { Timer t = new Timer() { public void run() { BaseDialog.this.setVisible(false); } }; t.schedule(autoCloseSecs * 1000); } } public void setHideAlgorythm(HideType type) { _hideAlgorithm = type; } public HideType getHideAlgorythm() { return _hideAlgorithm; } public void setDefaultContentSize(int w, int h) { _popup.setDefaultSize(w, h); _sizeSet = true; } public void setContentMinWidth(int minWidth) { _popup.setContentMinWidth(minWidth); } public void setContentMinHeight(int minHeight) { _popup.setContentMinHeight(minHeight); } public Widget getDialogWidget() { return _popup.getPopupPanel(); } public final void doCancel() { setContainerVisible(false); inputCanceled(); } public HandlerRegistration addClickHandler(final ClickHandler l) { _clickList.add(l); return new HandlerRegistration() { public void removeHandler() { if (_clickList.contains(l)) _clickList.remove(l); } }; } /** * Enable/disable locating the dialog on browser or dialog resize * Must be called after visible or will have no effect * @param autoLocate enable/diable auto locating */ public void setAutoLocate(boolean autoLocate) { _popup.setAutoLocate(autoLocate); } public void alignToCenter() { _popup.alignTo(null, PopupPane.Align.CENTER, 0, 0); } public void alignTo(Widget widget, PopupPane.Align alignAt) { _popup.alignTo(widget, alignAt, 3, 3); } public Widget getButtonsWidget() { return _buttons; } //====================================================================== //------------------ Private / Protected Methods ----------------------- //====================================================================== private void callListeners(ClickEvent ev) { for (ClickHandler h : _clickList) h.onClick(ev); } private void buildDialog() { createButtons(); buildContents(); } private void buildContents() { } private void createButtons() { _buttons.addStyleName("base-dialog-buttons"); _buttons.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT); boolean addHelp = false; if (_type.getIDs() != null) { for (ButtonID id : _type.getIDs()) { if (id == ButtonID.HELP) addHelp = true; else addButton(id); } } if (_helpID != null || addHelp) { _buttons.add(HelpManager.makeHelpIcon(_helpID)); } } private void addButton(ButtonID id) { Button b = new DialogButton(id); _buttons.add(b); } //====================================================================== //------------------ Private Button Click Methods ---------------------- //====================================================================== private void doOKClick(ClickEvent ev, HideType hideAlgorythm) { try { if (validateInput()) { if (hideAlgorythm == HideType.BEFORE_COMPLETE) { setContainerVisible(false); } performInputComplete(ev, hideAlgorythm); } } catch (ValidationException e) { PopupUtil.showError("Error", e.getMessage()); } } private void doCancelClick(ClickEvent ev) { doCancel(); callListeners(ev); } private void doRemoveClick(ClickEvent ev) { setContainerVisible(false); performInputComplete(ev); } private void doHelpClick(ClickEvent ev) { Application.getInstance().getHelpManager().showHelpAt(_helpID); callListeners(ev); } //====================================================================== //------------------ Private Methods ----------------------------------- //====================================================================== private void setContainerVisible(boolean v) { setContainerVisible(v, null, Integer.MIN_VALUE, Integer.MIN_VALUE); } private void setContainerVisible(boolean v, PopupPane.Align alignAt, int xOffset, int yOffset) { if (v) { alignAt = alignAt == null ? PopupPane.Align.CENTER : alignAt; if (xOffset == Integer.MIN_VALUE || yOffset == Integer.MIN_VALUE) { _popup.alignTo(_parent, alignAt); } else { _popup.alignTo(_parent, alignAt, xOffset, yOffset); } _popup.show(); } else { _popup.hide(); } } private void addButtonAttributes(DialogButton b) { ButtonID bID = b.getID(); switch (bID) { case NO_BUTTON: b.setText("NO BUTTON"); break; case OK: b.setText(OK_TXT); b.addStyleName("highlight-text"); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doOKClick(ev, _hideAlgorithm); } }); break; case APPLY: b.setText(APPLY_TXT); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doOKClick(ev, HideType.DONT_HIDE); } }); break; case CANCEL: b.setText(CANCEL_TXT); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doCancelClick(ev); } }); break; case HELP: b.setText(HELP_TXT); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doHelpClick(ev); } }); break; case REMOVE: b.setText(REMOVE_TXT); b.addStyleName("highlight-text"); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doRemoveClick(ev); } }); break; case YES: b.setText(YES_TXT); b.addStyleName("highlight-text"); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doOKClick(ev, _hideAlgorithm); } }); break; case NO: b.setText(NO_TXT); b.addClickHandler(new ClickHandler() { public void onClick(ClickEvent ev) { doCancelClick(ev); } }); break; case USER: break; default: assert false; // unrecognized button type break; } } public void performInputComplete(final ClickEvent ev) { performInputComplete(ev, _hideAlgorithm); } public void performInputComplete(final ClickEvent ev, final HideType hideAlgorythm) { inputCompleteAsync(new AsyncCallback<String>() { public void onFailure(Throwable caught) { } public void onSuccess(String result) { callListeners(ev); if (hideAlgorythm == HideType.AFTER_COMPLETE) setVisible(false); } }); } public void inputCompleteAsync(AsyncCallback<String> cb) { inputComplete(); cb.onSuccess("ok"); } /** * This method should return true if input is valid and false if it is not. * If this method returns false the dialog will not be removed. In the case of * returning false then the method is responsible for telling the user why the * input is invalid (such as by calling GwtUtil.showMsg). * * Alternatively, for convenience in the failure case, the dialog may throw a DialogInputException. * The message in the exception will be show to the user using GwtUtil.showMsg. * * @return true if success, false if failure * @throws ValidationException thrown in failure case when you want to show the * user a message that he must acknowledge. The exception exist only for convenience. * It is optional it you wish to use it. * */ protected boolean validateInput() throws ValidationException { return true; } protected void inputComplete() { } protected void inputCanceled() { } protected void onFirstVisible() { } protected void onVisible() { } protected void deferredBuild() { } public class DialogButton extends Button { public final BaseDialog.ButtonID _id; public DialogButton(BaseDialog.ButtonID id) { super(""); _id = id; addButtonAttributes(this); } public ButtonID getID() { return _id; } } private class DialogPopupPane extends PopupPane { DialogPopupPane(String header, Widget content, PopupType ptype, boolean modal, boolean autoHide) { super(header, content, ptype, modal, autoHide); } @Override protected void onCloseButtonClick(ClickEvent ev) { doCancelClick(ev); } } }