Java tutorial
/* * Copyright 2015 Valeriy Filatov. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package ru.fly.client.ui.field.combobox; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.InputElement; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.*; import com.google.gwt.user.client.ui.RootPanel; import ru.fly.client.F; import ru.fly.client.LastRespAsyncCallback; import ru.fly.client.event.SelectEvent; import ru.fly.client.event.UpdateHandler; import ru.fly.client.log.Log; import ru.fly.client.ui.FElement; import ru.fly.client.ListStore; import ru.fly.client.ui.listview.ListView; import ru.fly.client.Loader; import ru.fly.client.ui.field.TriggerField; import ru.fly.client.ui.grid.Getter; import ru.fly.client.event.SelectHandler; import ru.fly.client.util.LastPassExecutor; import java.util.List; /** * User: fil * Date: 05.08.13 * Time: 21:45 */ public class ComboBox<T> extends TriggerField<T> { private final ComboBoxDecor decor; private Loader<String, List<T>> loader; private ListStore<T> store = new ListStore<T>(); private ListView<T> listView; private Getter<T> getter; private boolean hasEmpty; private String query = null; private LastPassExecutor queryExec = new LastPassExecutor() { @Override protected void exec(Object param) { if (param != null && ((String) param).isEmpty()) param = null; if (query != param) { if (param == null) query = null; else query = param.toString(); store.clear(); expander.expand(true); } } }; private String loaderUID = F.getUID(); private boolean selectOnly = true; private boolean needRedraw = false; private boolean alwaysLoad = false; public ComboBox(Getter<T> getter) { this(GWT.<ComboBoxDecor>create(ComboBoxDecor.class), getter); } public ComboBox(ComboBoxDecor decor, Getter<T> getter) { this.decor = decor; addStyleName(decor.css().comboBox()); setGetter(getter); store.addUpdateHandler(new UpdateHandler() { @Override public void onUpdate() { needRedraw = true; } }); } @Override protected FElement buildTriggerElement() { FElement ret = DOM.createDiv().cast(); ret.addClassName(decor.css().comboBoxTrigger()); FElement trIcon = DOM.createDiv().cast(); ret.appendChild(trIcon); trIcon.setClassName(decor.css().comboBoxTriggerIcon()); return ret; } @Override public void onAfterFirstAttach() { super.onAfterFirstAttach(); view.addClassName(decor.css().comboBoxView()); setSelectOnly(selectOnly); if (tr == null) { addStyleName(decor.css().untriggered()); } } @Override protected FElement getExpandedElement() { return getListView().getElement(); } @Override protected FElement buildViewElement() { return DOM.createInputText().cast(); } public void setGetter(Getter<T> getter) { this.getter = getter; } public void setSelectOnly(boolean selectOnly) { this.selectOnly = selectOnly; if (view != null) { ((InputElement) view.cast()).setReadOnly(selectOnly); } } public void setAlwaysLoad(boolean val) { alwaysLoad = val; } @Override protected void onAttach() { super.onAttach(); DOM.setEventListener(view, new EventListener() { @Override public void onBrowserEvent(Event event) { if (event.getTypeInt() == Event.ONKEYUP && !selectOnly) { queryExec.pass(((InputElement) view.cast()).getValue()); } } }); DOM.sinkEvents(view, Event.ONKEYUP); } /** * ? ? ? */ public void invalidate() { clear(); store.clear(); } @Override public void setValue(T value) { super.setValue(value); if (view != null) { String str = ""; // ? NULL try { str = getter.get(value); } catch (Exception e) { Log.warn("? NULL", e); } ((InputElement) view.cast()).setValue(str); } getListView().select(value, false); } public void setHasEmpty(boolean val) { hasEmpty = val; } public void setLoader(Loader<String, List<T>> loader) { this.loader = loader; } private void updatePositionAndSize() { if (!expander.isExpanded()) return; int top = getElement().getAbsoluteTop() + getHeight(); int left = getElement().getAbsoluteLeft(); int wndViewHeight = Window.getClientHeight() + Window.getScrollTop() - 20; int height = getListView().getMaxHeight(); if (top < wndViewHeight / 2) { if (height > wndViewHeight - top) { height = wndViewHeight - top; } } else { if (height > getElement().getAbsoluteTop() - 20) { height = getElement().getAbsoluteTop() - 20; top = 20; } else { top = getElement().getAbsoluteTop() - height; } } if (getListView().getWidth() < getWidth()) getListView().setWidth(getWidth()); getListView().setHeight(height); getListView().setPosition(left, top); } private ListView<T> getListView() { if (listView == null) { listView = new ListView<T>(getter); listView.addSelectHandler(new SelectHandler<T>() { @Override public void onSelect(T object) { expander.collapse(); setValue(object); fireEvent(new SelectEvent<T>(object)); } }); listView.addStyleName(decor.css().listView()); } return listView; } @Override protected void onExpand() { getListView().setPosition(-10000, -10000); RootPanel.get().add(getListView()); if (alwaysLoad || needRedraw || store.isEmpty() || query != null) { getListView().setLoading(); load(); } updatePositionAndSize(); } @Override protected void onCollapse() { getListView().removeFromParent(); if (query != null && !query.isEmpty()) { query = null; store.clear(); } } private void load() { if (loader != null) { loader.load(query, new LastRespAsyncCallback<List<T>>(loaderUID) { @Override public void onSuccessLast(List<T> result) { store.fill(result); redrawListView(); } @Override public void onFailureLast(Throwable caught) { store.clear(); redrawListView(); } }); } else { redrawListView(); } } public String getQuery() { return query; } public void redrawListView() { if (isAttached()) { getListView().fillData(store.getList(), hasEmpty); getListView().getStyle().clearWidth(); } updatePositionAndSize(); needRedraw = false; } public ListStore<T> getStore() { return store; } public HandlerRegistration addSelectHandler(SelectHandler<T> handler) { return addHandler(handler, SelectEvent.<T>getType()); } }