如何在 GWT 中实现 JQueryUI 滑块

2024-03-31

我最近需要在 GWT 中实现一个滑块来捕获用户在任务上取得的进度百分比。我对 GWT 孵化器中的滑块并不满意,并且不太热衷于使用 spiffy UI 或 SmartGWT 等外部库。我可以使用哪些替代方案在 GWT 中实现有效的滑块,而不需要做太多的麻烦工作?


经过大量搜索后,我决定使用 JQuery-Ui 滑块,该滑块将通过 java 包装器类实现。 GWT 和 JQuery 滑块之间的交互将通过 GWT Java Script Native Interface 进行。为了使所需库的添加尽可能小,我下载了一个自定义的 Jquery-Ui 包(只是 core+slider),它的重量相当轻。结果满足了我们的需求,符合我们的 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] /cdn-cgi/l/email-protection::fireOnStartEvent(Lcom/google/gwt/user/client/Event;I)(event, ui.value);
        };
        options.slide = function(event, ui) {
            return [email protected] /cdn-cgi/l/email-protection::fireOnSlideEvent(Lcom/google/gwt/user/client/Event;I)(event, ui.value);
        };
        options.change = function(event, ui) {
            var has = event.originalEvent ? true : false;
            [email protected] /cdn-cgi/l/email-protection::fireOnChangeEvent(Lcom/google/gwt/user/client/Event;IZ)(event, ui.value, has);
        };
        options.stop = function(event, ui) {
            [email protected] /cdn-cgi/l/email-protection::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/ http://www.zackgrossbart.com/hackito/gwt-slider/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 GWT 中实现 JQueryUI 滑块 的相关文章

随机推荐

  • 尝试拟合 CrossValidator 对象时 DataBricks PySpark 出错

    首先 我是 DataBricks 和 PySpark 的新手 所以如果这是我没有看到的简单解决方案 我深表歉意 我的集群位于 DataBricks 运行时 9 1 LTS Spark 3 1 2 Scala 2 12 上 我正在研究一个 N
  • 在 Perl 中如何使用变量作为变量名?

    我需要在 perl 中实现以下目标 printmsg val1 msg1 if val1 printmsg val2 msg2 if val2 printmsg val3 msg3 if val3 printmsg val4 msg4 if
  • return 语句之前/期间的 C 分段错误

    我在 return 语句之前打印要返回的值 并告诉我的代码打印在函数调用之后立即返回的值 但是 在第一个打印语句之后和第二个打印语句之前 我遇到了分段错误 还值得注意的是 这种情况总是发生在第三次调用该函数时 从来没有第一次或第二次 也从来
  • 修改访客的捆绑属性

    我应该如何从访问者内部修改顶点的捆绑属性 我想使用对图进行子脚本化的简单方法 但传递给访问者的图参数是 const 因此编译器不允许更改 我可以在访问者中存储对图表的引用 但这看起来很奇怪 A visitor which identifie
  • 计算 Java 对象的值?

    我有一个用于存储项目的 Java 对象 public class PaymentDetailsItem private String name private String amount private int quantity priva
  • 在 Excel5.php 中找不到类“PHPExcel”

    我在 PHPExcel 中收到以下错误 Fatal error Class PHPExcel not found in PHPExcel Reader Excel5 php on line 587 这很奇怪 因为我在网上搜索时没有遇到过它
  • 尽管 rake 路线中有一条路线,但没有路线匹配

    我变得奇怪ActionController RoutingError No route matches 可以生成路线 gt r Rails application routes gt r generate controller items
  • 通用语言对 PCRE(Perl 兼容正则表达式)有哪些支持?

    我对 PCRE Perl 兼容正则表达式 的强大功能很感兴趣 并且想知道它们是否有可能成为所有主要语言中事实上的方法 我对 Java 感兴趣 如果有必要 我准备使用图书馆 我也无法在 SO 中找到一个很好的页面来描述 PCRE 的优缺点 因
  • Web 服务存根生成 + android

    我想生成一个基于 android java 的 STUB 来访问所有 Web 服务 我尝试使用以下工具生成存根 1 用于 CLDC 的 Sun Java TM 无线工具包 2 5 2 01 2 ksoap2 生成 stub 0 1 SNAP
  • 我可以使用特征稀疏矩阵来满足一般存储需求吗

    我需要一个模板化的稀疏矩阵实现 但只是为了减少内存占用 not进行任何数值求解 所以我尝试使用 Eigen 尽管我不需要数学部分 为什么 它恰好就在我的机器上 而且我已经用它来做其他事情了 但我肯定不是本征专家 Context 我有一个类型
  • 使用 LINQ 查询初始化 List

    我正在初始化一个List
  • Perl chomp 将多位数字变成 1 或 0

    我遇到一种情况 我需要用 Perl 读取一个充满数字的文件 这本身工作得很好 但是当我尝试删除每一行时 它会将以前的 5 或 6 位数字变成 1 或 0 Ideas 我需要对数字进行咀嚼以将文件路径与它们组合起来 因此回车符是一个问题 你没
  • 如何从 BroadcastReceiver 发出通知?

    如何从 BroadcastReceiver 发出通知 不能使用大多数方法 也不能使用 this 我需要它来打开一个包含数据库信息的活动我已经做到了 但现在必须的方法不起作用 我不能使用 这个 In the onReceive方法你得到一个C
  • LibGDX 将 BitmapFont 绘制到中间位置(spritebatch)

    我想使用 BitmapFont 绘制一些文本 临时位置 然后绘制该位置的一部分 到最后的精灵批次 我当时正在考虑画画 到临时 spritebatch 但不可能 将 spritebatch 绘制到另一个上 我怎样才能做到这一点 您可以使用帧缓
  • C - 返回指向局部变量的指针的函数

    考虑以下代码 include
  • Oracle 10g PL/SQL Connect By Prior 返回同一行上的子级和父级

    Table1 Child Parent a Bob Chris 2 Chris Kate 1 Shane Lana 3 Nala Bob 4 Table2 b Talent 1 something 2 nothing 3 something
  • CurrentThreadTaskScheduler 未完成同步

    我尝试为视图模型编写单元测试 但在尝试验证 ICommand 调用异步方法两次时遇到了困难 我使用 Moq 作为我的依赖项 我像这样设置了异步方法 this communicationServiceFake Setup x gt x Wri
  • 将列表的 2 个数据框中的因子转换为数值

    我在将列表中 2 个数据框的列转换为数字时遇到问题 现在两个数据框都有 2 列由因素组成 我想将它们转换为数字 以便我可以对它们进行数学运算 下面是示例代码 library XML bal lt http www baseball refe
  • 为什么不总是使用 HTTP post 进行 ajax 调用?

    我知道 HTTP get 和 post 方法之间的区别 如详细信息中所述this https stackoverflow com questions 46585 when do you use post and when do you us
  • 如何在 GWT 中实现 JQueryUI 滑块

    我最近需要在 GWT 中实现一个滑块来捕获用户在任务上取得的进度百分比 我对 GWT 孵化器中的滑块并不满意 并且不太热衷于使用 spiffy UI 或 SmartGWT 等外部库 我可以使用哪些替代方案在 GWT 中实现有效的滑块 而不需