2014-09-04 124 views
2

我最近需要在GWT中實現滑塊來捕獲用戶在任務上所取得的百分比進度。我對GWT孵化器的滑塊並不滿意,也不太喜歡使用像Spiffy UI或SmartGWT這樣的外部庫。我可以用什麼替代方法來實現GWT中的有效滑動,而不需要做太多的驢工作?如何在GWT中實現JQueryUI滑塊

+0

這應該是一個「問題」? – 2014-09-04 12:19:50

+0

更好?對不起這個新的 – 2014-09-04 12:24:31

回答

1

經過大量的搜索之後,我決定使用一個可以通過java包裝類實現的JQuery-Ui滑塊。 GWT和JQuery滑塊之間的交互將通過GWT Java腳本本地接口。爲了使所需的庫儘可能小,我下載了一個非常輕的自定義Jquery-UI包(只是核心+滑塊)。結果滿足我們的需求,符合我們的MVP設計模式,並且是UI綁定。

滑塊包裝如下:然後

package za.co.bsg.ems.client.framework.ui.slider; 

import com.google.gwt.core.client.JavaScriptObject; 
import com.google.gwt.json.client.JSONNumber; 
import com.google.gwt.json.client.JSONObject; 
import com.google.gwt.json.client.JSONString; 
import com.google.gwt.user.client.DOM; 
import com.google.gwt.user.client.Element; 
import com.google.gwt.user.client.Event; 
import com.google.gwt.user.client.ui.Widget; 

import java.util.ArrayList; 
import java.util.List; 


/** 
* This widget wraps the JQuery UI Slider and allows for single slider . 
* 
* All options can be get or set using generic get/setIntOption, get/setStringOption, get/setBooleanOption 
* methods, but some convenience methods are provided for most popular such as 
* setValues and setMinimum and setMaximum. See SliderOptions for full list of options. 
* @see SliderOption 
* 
*/ 
@SuppressWarnings("Convert2Diamond") 
public class SingleSlider extends Widget { 

    private JSONObject defaultOptions; 
    private List<SliderListener> listeners = new ArrayList<SliderListener>(); 

    /** 
    * Create the default slider with the specified ID. The ID is required 
    * because the slider needs a specific ID to connect to. 
    * @param id - id of the element to create 
    */ 
    public SingleSlider(String id) { 
     this(id, null);   
    } 

    /** 
    * Create a slider with the specified ID. The ID is required 
    * because the slider needs a specific ID to connect to. 
    * @param id - id of the element to create 
    * @param options - JSONObject of any possible option, can be null for defaults 
    */ 
    public SingleSlider(String id, JSONObject options) { 
     super(); 
     Element divEle = DOM.createDiv(); 
     setElement(divEle); 
     divEle.setId(id); 

     defaultOptions = options; 
     if (defaultOptions == null) { 
      defaultOptions = getOptions(0, 100, 0); 
     }   
    } 

    /** 
    * A convenient way to create an options JSONObject. Use SliderOption for keys. 
    * @param min - default minimum of the slider 
    * @param max - default maximum of the slider 
    * @param defaultValue - default point of anchor 
    * @return a JSONObject of Slider options 
    */ 
    public static JSONObject getOptions(int min, int max, int defaultValue) { 
     JSONObject options = new JSONObject(); 
     options.put(SliderOption.MIN.toString(), new JSONNumber(min)); 
     options.put(SliderOption.MAX.toString(), new JSONNumber(max)); 
     options.put(SliderOption.VALUE.toString(), new JSONNumber(defaultValue)); 
     options.put(SliderOption.RANGE.toString(), new JSONString("min")); 
     return options; 
    } 

    @Override 
    protected void onLoad() { 
     createSliderJS(this, getElement().getId(), defaultOptions.getJavaScriptObject()); 
     super.onLoad(); 
    } 

    @Override 
    protected void onUnload() { 
     destroySliderJS(this, getElement().getId()); 
     super.onUnload();   
    } 
    /** 
    * Gets the minimum possible value for the slider 
    * @return Returns the minimum. 
    */ 
    public int getMinimum() { 
     return getIntOptionJS(getElement().getId(), SliderOption.MIN.toString()); 
    } 

    /** 
    * Sets the minimum possible value for the slider 
    * @param minimum The minimum to set. 
    */ 
    public void setMinimum(int minimum) { 
     setIntOptionJS(getElement().getId(), SliderOption.MIN.toString(), minimum); 
    } 

    /** 
    * Gets the maximum possible value for the slider 
    * @return Returns the maximum. 
    */ 
    public int getMaximum() { 
     return getIntOptionJS(getElement().getId(), SliderOption.MAX.toString()); 
    } 

    /** 
    * Sets the maximum possible value for the slider 
    * @param maximum The maximum to set. 
    */ 
    public void setMaximum(int maximum) { 
     setIntOptionJS(getElement().getId(), SliderOption.MAX.toString(), maximum); 
    } 

    /** 
    * Convenience method for only 1 anchor 
    * @param value to set. 
    */ 
    public void setValue(int value) { 
     setValueJS(getElement().getId(), value); 
    } 


    /** 
    * Set an option numeric value 
    * @param option the SliderOption 
    * @param value the numeric 
    */ 
    public void setIntOption(SliderOption option, int value) { 
     setIntOptionJS(getElement().getId(), option.toString(), value); 
    } 

    /** 
    * Get an option numeric value 
    * @param option the SliderOption 
    * @return value the numeric 
    */ 
    public int getIntOption(SliderOption option) { 
     return getIntOptionJS(getElement().getId(), option.toString()); 
    } 

    /** 
    * Set an option boolean value 
    * @param option the SliderOption 
    * @param value the boolean 
    */ 
    public void setBooleanOption(SliderOption option, boolean value) { 
     setBooleanOptionJS(getElement().getId(), option.toString(), value); 
    } 

    /** 
    * Get an option boolean value 
    * @param option the SliderOption 
    * @return value the boolean 
    */ 
    public boolean getBooleanOption(SliderOption option) { 
     return getBooleanOptionJS(getElement().getId(), option.toString()); 
    } 

    /** 
    * Set an option string value 
    * @param option the SliderOption 
    * @param value the String 
    */ 
    public void setStringOption(SliderOption option, String value) { 
     setStringOptionJS(getElement().getId(), option.toString(), value); 
    } 

    /** 
    * Set an option string value 
    * @param option the SliderOption 
    * @return value the String 
    */ 
    public String setStringOption(SliderOption option) { 
     return getStringOptionJS(getElement().getId(), option.toString()); 
    } 

    /** 
    * Add a SliderListener 
    * @param l - SliderListener 
    */ 
    public void addListener(SliderListener l) { 
     listeners.add(l); 
    } 

    /** 
    * Removes the SliderListener 
    * @param l - SliderListener 
    */ 
    public void removeListener(SliderListener l) { 
     listeners.remove(l); 
    } 


    private void fireOnStartEvent(Event evt, int value) { 
     SliderEvent e = new SliderEvent(evt, this, value); 

     for (SliderListener l : listeners) { 
      l.onStart(e); 
     } 
    } 

    private boolean fireOnSlideEvent(Event evt, int value) { 
     SliderEvent e = new SliderEvent(evt, this, value); 

     for (SliderListener l : listeners) { 
      l.onStart(e); 
     } 

     boolean ret = true; 

     for (SliderListener l : listeners) { 
      if (!l.onSlide(e)) { 
       //if any of the listeners returns false, return false, 
       //but let them all do their thing 
       ret = false; 
      } 
     } 

     return ret; 
    } 

    private void fireOnChangeEvent(Event evt, int value, boolean hasOriginalEvent) { 
     SliderEvent e = new SliderEvent(evt, this, value, hasOriginalEvent); 

     for (SliderListener l : listeners) { 
      l.onChange(e); 
     } 
    } 

    private void fireOnStopEvent(Event evt, int value) { 
     SliderEvent e = new SliderEvent(evt, this, value); 

     for (SliderListener l : listeners) { 
      l.onStop(e); 
     } 
    } 


    private native void setIntOptionJS(String id, String option, int value) /*-{ 
     $wnd.$("#" + id).slider("option", option, value); 
    }-*/; 


    private native int getIntOptionJS(String id, String option) /*-{ 
     return $wnd.$("#" + id).slider("option", option); 
    }-*/; 


    private native void setBooleanOptionJS(String id, String option, boolean value) /*-{ 
     $wnd.$("#" + id).slider("option", option, value); 
    }-*/; 


    private native boolean getBooleanOptionJS(String id, String option) /*-{ 
     return $wnd.$("#" + id).slider("option", option); 
    }-*/; 


    private native void setStringOptionJS(String id, String option, String value) /*-{ 
     $wnd.$("#" + id).slider("option", option, value); 
    }-*/; 


    private native String getStringOptionJS(String id, String option) /*-{ 
     return $wnd.$("#" + id).slider("option", option); 
    }-*/; 

    private native void setValueJS(String id, int value) /*-{ 
     $wnd.$("#" + id).slider("option", "value", value); 
    }-*/; 


    private native void createSliderJS(SingleSlider x, String id, JavaScriptObject options) /*-{ 
     options.start = function(event, ui) { 
      [email protected]::fireOnStartEvent(Lcom/google/gwt/user/client/Event;I)(event, ui.value); 
     }; 
     options.slide = function(event, ui) { 
      return [email protected]::fireOnSlideEvent(Lcom/google/gwt/user/client/Event;I)(event, ui.value); 
     }; 
     options.change = function(event, ui) { 
      var has = event.originalEvent ? true : false; 
      [email protected]::fireOnChangeEvent(Lcom/google/gwt/user/client/Event;IZ)(event, ui.value, has); 
     }; 
     options.stop = function(event, ui) { 
      [email protected]::fireOnStopEvent(Lcom/google/gwt/user/client/Event;I)(event, ui.value); 
     }; 

     $wnd.$("#" + id).slider(options); 
    }-*/; 


    private native void destroySliderJS(SingleSlider x, String id) /*-{ 
     $wnd.$("#" + id).slider("destroy"); 
    }-*/; 
} 

該滑塊被納入以下小部件創建一個百分比滑塊

package za.co.bsg.ems.client.framework.ui.slider; 

import com.google.gwt.core.client.GWT; 
import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 
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.json.client.JSONObject; 
import com.google.gwt.uibinder.client.UiBinder; 
import com.google.gwt.uibinder.client.UiField; 
import com.google.gwt.user.client.ui.Composite; 
import com.google.gwt.user.client.ui.IntegerBox; 
import com.google.gwt.user.client.ui.Label; 
import com.google.gwt.user.client.ui.Widget; 
import za.co.bsg.ems.client.event.IntegerValueChangeEvent; 

import java.util.HashSet; 
import java.util.Set; 

public class PercentageSliderWidget extends Composite implements SliderListener, HasValueChangeHandlers<Integer> { 

    interface PercentageSliderUiBinder extends UiBinder<Widget, PercentageSliderWidget> {} 
    private static final PercentageSliderUiBinder UI_BINDER = GWT.create(PercentageSliderUiBinder.class); 

    @UiField 
    Label headingLabel; 
    @UiField(provided = true) 
    SingleSlider singleSlider; 
    @UiField 
    IntegerBox percentBox; 
    @UiField 
    Label percentageSignLabel; 

    private Set<ValueChangeHandler<Integer>> valueChangeHandlers; 

    public PercentageSliderWidget(long taskId, String heading, int existingProgress) { 
     valueChangeHandlers = new HashSet<>(); 
     JSONObject options = SingleSlider.getOptions(0, 100, existingProgress); 
     singleSlider = new SingleSlider("singleSlider" + taskId, options); 
     singleSlider.setTitle(existingProgress + "%"); 
     initWidget(UI_BINDER.createAndBindUi(this)); 
     singleSlider.addListener(this); 
     percentBox.setValue(existingProgress); 
     percentBox.addValueChangeHandler(new ValueChangeHandler<Integer>() { 
      @Override 
      public void onValueChange(ValueChangeEvent<Integer> event) { 
       updateValues(event.getValue(), true); 
      } 
     }); 
     headingLabel.setText(heading); 
     percentageSignLabel.setText("%"); 
    } 

    public void setValue(int value) { 
     updateValues(value, false); 
    } 

    @Override 
    public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<Integer> handler) { 
     valueChangeHandlers.add(handler); 
     return new HandlerRegistration() { 
      @Override 
      public void removeHandler() { 
       valueChangeHandlers.remove(handler); 
      } 
     }; 
    } 

    @Override 
    public boolean onSlide(SliderEvent e) { 
     percentBox.setValue(e.getValue()); 
     return true; 
    } 

    @Override 
    public void onChange(SliderEvent e) { 
     // do nothing 
    } 

    @Override 
    public void onStop(SliderEvent e) { 
     updateValues(e.getValue(), true); 
    } 

    @Override 
    public void onStart(SliderEvent e) { 
     // do nothing 
    } 

    private void updateValues(int progressValue, boolean fireEvents) { 
     singleSlider.setTitle(progressValue + "%"); 
     singleSlider.setValue(progressValue); 
     percentBox.setValue(progressValue); 
     if (fireEvents) { 
      for (ValueChangeHandler<Integer> valueChangeHandler : valueChangeHandlers) { 
       valueChangeHandler.onValueChange(new IntegerValueChangeEvent(progressValue)); 
      } 
     } 
    } 

} 

我的出發資源是以下 http://www.zackgrossbart.com/hackito/gwt-slider/

+1

我從未更加感謝能夠使用純JavaScript工作......:P – 2014-09-04 12:43:32