blob: c94e20888a779e2b999b8322553d2a8d5be9e1a7 [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.UpdateValueStrategy;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableSelectionEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableValueEndpoint;
import org.eclipse.osbp.ecview.core.common.notification.IReloadRequestService;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextField;
import org.eclipse.osbp.ecview.core.extension.model.extension.YSuggestTextFieldEvents;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.ISuggestTextFieldEditpart;
import org.eclipse.osbp.runtime.common.annotations.DtoUtils;
import org.eclipse.osbp.runtime.common.annotations.HistIsCurrent;
import org.eclipse.osbp.runtime.common.historized.UUIDHist;
import org.eclipse.osbp.runtime.common.state.ISharedStateContext;
import org.eclipse.osbp.runtime.common.util.BeanUtils;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;
import org.eclipse.osbp.runtime.web.vaadin.common.data.BeanServiceLazyLoadingContainer;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IBeanSearchServiceFactory;
import org.eclipse.osbp.runtime.web.vaadin.common.data.IGlobalFilterable;
import org.eclipse.osbp.vaadin.addons.suggesttext.SuggestTextField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.SimpleDateFormat;
import com.vaadin.data.Container;
import com.vaadin.data.sort.SortOrder;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.data.util.converter.Converter;
import com.vaadin.data.util.filter.Compare;
import com.vaadin.data.util.filter.Compare.Equal;
import com.vaadin.server.ErrorMessage;
import com.vaadin.shared.data.sort.SortDirection;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;
import com.vaadin.ui.Component.Focusable;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.Field;
import com.vaadin.ui.Grid;
import com.vaadin.ui.Grid.Column;
import com.vaadin.ui.Grid.SelectionMode;
import com.vaadin.ui.NativeButton;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
/**
* This presenter is responsible to render a text field on the given layout.
*/
public class SuggestTextFieldPresentation extends AbstractFieldWidgetPresenter<Component> {
private static final Logger LOGGER = LoggerFactory.getLogger(SuggestTextFieldPresentation.class);
/** The model access. */
private final ModelAccess modelAccess;
/** The text. */
private SuggestTextField text;
/** The property. */
private ObjectProperty<String> property;
/** The adapter. */
private Adapter adapter;
/** The value binding. */
private Binding valueBinding;
private Binding keyBinding;
private boolean updateBinding;
private Equal histCurrentFilter;
private Binding dtoBinding;
/**
* Constructor.
*
* @param editpart
* The editpart of that presenter
*/
public SuggestTextFieldPresentation(IElementEditpart editpart) {
super((ISuggestTextFieldEditpart) editpart);
this.modelAccess = new ModelAccess((YSuggestTextField) editpart.getModel());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings({ "unchecked", "rawtypes", "serial" })
@Override
public Component doCreateWidget(Object parent) {
if (text == null) {
adapter = new Adapter();
modelAccess.yField.eAdapters().add(adapter);
text = new CustomTextField();
text.addStyleName(CSS_CLASS_CONTROL);
text.getTextField().setNullRepresentation("");
text.setImmediate(true);
text.setLimit(10);
text.setAutoHide(modelAccess.yField.isAutoHidePopup());
text.setShowHistoryDialogCallback(() -> showHistorizedDialog());
if (BeanUtils.isHistorized(modelAccess.yField.getType())) {
text.setHistorized(true);
}
setupComponent(text, getCastedModel());
associateWidget(text, modelAccess.yField);
associateWidget(text.getTextField(), modelAccess.yField);
if (modelAccess.isCssIdValid()) {
text.setId(modelAccess.getCssID());
} else {
text.setId(getEditpart().getId());
}
property = new ObjectProperty<>(null, String.class);
text.getTextField().setPropertyDataSource(property);
text.addSelectionChangedListener(new SuggestTextField.SelectionChangedListener() {
@Override
public void selectionChanged(SuggestTextField.SelectionChangedEvent event) {
Object itemId = event.getItemId();
internalSetLastSuggestion(itemId);
}
});
if (modelAccess.yField.getType() != null) {
IBeanSearchServiceFactory factory = getViewContext()
.getService(IBeanSearchServiceFactory.class.getName());
if (factory != null) {
ISharedStateContext sharedState = getViewContext().getService(ISharedStateContext.class.getName());
BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer(
factory.createService(modelAccess.yField.getType()), modelAccess.yField.getType(),
sharedState);
text.setContainerDataSource(datasource);
text.setCaptionPropertyId(modelAccess.yField.getItemCaptionProperty());
text.setCaptionPropertyRetriever((dto) -> {
if (dto == null) {
return "";
}
return (String) DtoUtils.getValue(dto, modelAccess.yField.getItemCaptionProperty());
});
text.setFilterPropertyId(modelAccess.yField.getItemFilterProperty());
String uuidProp = modelAccess.yField.getItemUUIDProperty();
if (uuidProp != null && !uuidProp.equals("")) {
text.setUniqueIdPropertyId(modelAccess.yField.getItemUUIDProperty());
}
}
}
// creates the binding for the field
createBindings(modelAccess.yField, text);
if (modelAccess.isCssClassValid()) {
text.addStyleName(modelAccess.getCssClass());
}
applyCaptions();
initializeField(text.getTextField());
}
return text;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
*/
@Override
protected void doUpdateLocale(Locale locale) {
// no need to set the locale to the ui elements. Is handled by vaadin
// internally.
// update the captions
applyCaptions();
}
/**
* Applies the labels to the widgets.
*/
protected void applyCaptions() {
Util.applyCaptions(getI18nService(), modelAccess.getLabel(), modelAccess.getLabelI18nKey(), getLocale(), text);
}
protected void showHistorizedDialog() {
new DialogHandleImp().open();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractFieldWidgetPresenter#doGetField()
*/
@Override
protected Field<?> doGetField() {
return text != null ? text.getTextField() : null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
* AbstractVaadinWidgetPresenter
* #internalGetObservableEndpoint(org.eclipse.osbp
* .ecview.core.common.model.core.YEmbeddableBindingEndpoint)
*/
@Override
protected IObservable internalGetObservableEndpoint(YEmbeddableBindingEndpoint bindableValue) {
if (bindableValue == null) {
throw new IllegalArgumentException("BindableValue must not be null!");
}
if (bindableValue instanceof YEmbeddableValueEndpoint) {
return internalGetValueEndpoint();
} else if (bindableValue instanceof YEmbeddableSelectionEndpoint) {
return internalGetDtoEndpoint();
}
throw new IllegalArgumentException("Not a valid input: " + bindableValue);
}
/**
* Returns the observable to observe value.
*
* @return the i observable value
*/
@SuppressWarnings("rawtypes")
protected IObservableValue internalGetValueEndpoint() {
// return the observable value for text
return EMFObservables.observeValue(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__VALUE);
}
@SuppressWarnings("rawtypes")
protected IObservableValue internalGetDtoEndpoint() {
// return the observable value for the current dto
return EMFObservables.observeValue(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__CURRENT_VALUE_DTO);
}
/**
* Creates the bindings for the given values.
*
* @param yField
* the y field
* @param field
* the field
*/
protected void createBindings(YSuggestTextField yField, SuggestTextField field) {
updateValueBinding(field);
super.createBindings(yField, field, null);
}
/**
* The value binding takes respect to the
* modelAccess.yField.isUseSuggestions(). If suggestions are used, value
* changes in the UI MUST NOT be updated to the model.
*
* @param field
* the field
*/
protected void updateValueBinding(SuggestTextField field) {
if (valueBinding != null) {
unregisterBinding(valueBinding);
}
if (keyBinding != null) {
unregisterBinding(keyBinding);
}
if (dtoBinding != null) {
unregisterBinding(dtoBinding);
}
if (histCurrentFilter != null) {
IGlobalFilterable filterable = (IGlobalFilterable) field.getContainerDataSource();
filterable.removeGlobalContainerFilter(histCurrentFilter);
}
if (field == null) {
return;
}
try {
updateBinding = true;
// suppress suggestions
field.setSuggestionEnabled(false);
if (modelAccess.yField.isUseSuggestions()) {
if (BeanUtils.isHistorized(modelAccess.yField.getType())) {
java.lang.reflect.Field histCurrentField = BeanUtils.getField(modelAccess.yField.getType(),
HistIsCurrent.class);
if (histCurrentField != null) {
histCurrentFilter = new Compare.Equal(histCurrentField.getName(), true);
IGlobalFilterable filterable = (IGlobalFilterable) field.getContainerDataSource();
filterable.addGlobalContainerFilter(histCurrentFilter);
}
}
// in suggest mode do not update from UI to model
keyBinding = createBindingsByAccessor(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__KEYS, field, "keys",
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
valueBinding = createBindingsValue(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__VALUE, field.getTextField(),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
dtoBinding = createBindingsByAccessor(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__CURRENT_VALUE_DTO, field, "currentItemId",
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
} else {
keyBinding = createBindingsByAccessor(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__KEYS, field, "keys",
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
valueBinding = createBindingsValue(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__VALUE, field.getTextField(),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
dtoBinding = createBindingsByAccessor(castEObject(getModel()),
ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__CURRENT_VALUE_DTO, field, "currentItemId",
new UpdateValueStrategy(UpdateValueStrategy.POLICY_NEVER),
new UpdateValueStrategy(UpdateValueStrategy.POLICY_UPDATE));
}
field.setSuggestionEnabled(modelAccess.yField.isUseSuggestions());
// create the model binding from model to ECView-model
registerBinding(valueBinding);
registerBinding(keyBinding);
registerBinding(dtoBinding);
} finally {
updateBinding = false;
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* getWidget()
*/
@Override
public Component getWidget() {
return text;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
* isRendered()
*/
@Override
public boolean isRendered() {
return text != null;
}
/**
* {@inheritDoc}
*/
@Override
public void doUnrender() {
if (text != null) {
modelAccess.yField.eAdapters().remove(adapter);
adapter = null;
// unbind all active bindings
unbind();
Component parent = text.getParent();
if (parent instanceof ComponentContainer) {
((ComponentContainer) parent).removeComponent(text);
}
// remove assocations
unassociateWidget(text);
unassociateWidget(text.getTextField());
text = null;
}
}
/**
* Sets the use suggestions.
*
* @param newBooleanValue
* the new use suggestions
*/
public void setUseSuggestions(boolean newBooleanValue) {
updateValueBinding(text);
}
/**
* Executes the given event.
*
* @param event
*/
protected void doExecuteEvent(YSuggestTextFieldEvents event) {
if (!isRendered()) {
return;
}
if (modelAccess.yField.isAutoHidePopup()) {
LOGGER.warn("Using events with autoHidePopup==true, may cause side effects, "
+ "since a click to the UI outside the popup will close the popup automatically");
}
switch (event) {
case OPEN_POPUP:
text.openPopup();
break;
case CLOSE_POPUP:
text.closePopup();
break;
case NAVIGATE_NEXT:
text.navigateToNext();
break;
case NAVIGATE_PREV:
text.navigateToPrevious();
break;
case SELECT:
text.selectCurrent();
break;
case CLEAR:
text.setValue(null);
text.closePopup();
internalSetLastSuggestion(null);
break;
}
}
/**
* {@inheritDoc}
*/
@Override
protected void internalDispose() {
try {
unrender();
} finally {
super.internalDispose();
}
}
protected void internalSetLastHistorizedSuggestion(Object itemId) {
internalSetLastSuggestion(itemId);
}
protected void internalSetLastSuggestion(Object itemId) {
IReloadRequestService service = getViewContext().getService(IReloadRequestService.class.getName());
if (service != null && itemId != null) {
service.requestReload(getCastedModel(), itemId);
}
modelAccess.yField.setLastSuggestion(itemId);
if (itemId != null) {
modelAccess.yField.setEvent(YSuggestTextFieldEvents.SELECTED);
}
}
/**
* A helper class.
*/
private static class ModelAccess {
/** The y field. */
private final YSuggestTextField yField;
/**
* Instantiates a new model access.
*
* @param yField
* the y field
*/
public ModelAccess(YSuggestTextField yField) {
super();
this.yField = yField;
}
/**
* Gets the css class.
*
* @return the css class
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
*/
public String getCssClass() {
return yField.getCssClass();
}
/**
* Returns true, if the css class is not null and not empty.
*
* @return true, if is css class valid
*/
public boolean isCssClassValid() {
return getCssClass() != null && !getCssClass().equals("");
}
/**
* Gets the css id.
*
* @return the css id
* @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
*/
public String getCssID() {
return yField.getCssID();
}
/**
* Returns true, if the css id is not null and not empty.
*
* @return true, if is css id valid
*/
public boolean isCssIdValid() {
return getCssID() != null && !getCssID().equals("");
}
/**
* Returns the label.
*
* @return the label
*/
public String getLabel() {
return yField.getLabel();
}
/**
* Returns the label.
*
* @return the label i18n key
*/
public String getLabelI18nKey() {
return yField.getLabelI18nKey();
}
}
// @SuppressWarnings("serial")
// class HistorizedWrapper extends CustomComponent {
//
// private final Class<?> type;
// private Component content;
// private CustomTextField textField;
//
// private HistorizedWrapper(Class<?> type) {
// this.type = type;
// init();
// }
//
// protected void init() {
// content = createContent();
// setCompositionRoot(content);
// setSizeFull();
// }
//
// protected Component createContent() {
//
// textField = new CustomTextField();
// Component content = null;
// if (BeanUtils.isHistorized(type)) {
// HorizontalLayout layout = new HorizontalLayout();
// content = layout;
// layout.addComponent(textField);
//
// Button button = new Button("H");
// button.setSizeUndefined();
// layout.addComponent(button);
// button.addClickListener((e) -> {
// showHistorizedDialog();
// });
//
// layout.setExpandRatio(textField, 1.0f);
// } else {
// content = textField;
// }
//
// return content;
// }
//
// }
/**
* The Class CustomTextField.
*/
@SuppressWarnings("serial")
private class CustomTextField extends SuggestTextField implements Focusable {
private int tabIndex;
/*
* (non-Javadoc)
*
* @see com.vaadin.ui.AbstractComponent#getErrorMessage()
*/
@Override
public ErrorMessage getErrorMessage() {
if (isDisposed()) {
// after disposal, Vaadin will call this method once.
return null;
}
ErrorMessage message = super.getErrorMessage();
reportValidationError(message);
return message;
}
@Override
public void focus() {
if (getTextField() != null) {
getTextField().focus();
}
}
@Override
protected TextFieldCustom createTextField() {
return new TextFieldCustom() {
@Override
public ErrorMessage getErrorMessage() {
if (isDisposed()) {
// after disposal, Vaadin will call this method once.
return null;
}
ErrorMessage message = super.getErrorMessage();
reportValidationError(message);
return message;
}
};
}
@Override
public void setSuggestionEnabled(boolean suggestionEnabled) {
super.setSuggestionEnabled(suggestionEnabled);
if (!updateBinding) {
modelAccess.yField.setUseSuggestions(suggestionEnabled);
}
}
public int getTabIndex() {
return tabIndex;
}
@Override
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
}
}
/**
* The Class Adapter.
*/
private class Adapter extends AdapterImpl {
/*
* (non-Javadoc)
*
* @see
* org.eclipse.emf.common.notify.impl.AdapterImpl#notifyChanged(org.
* eclipse.emf.common.notify.Notification)
*/
@Override
public void notifyChanged(Notification msg) {
if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__USE_SUGGESTIONS) {
setUseSuggestions(msg.getNewBooleanValue());
} else if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__AUTO_HIDE_POPUP) {
text.setAutoHide(msg.getNewBooleanValue());
} else if (msg.getFeature() == ExtensionModelPackage.Literals.YSUGGEST_TEXT_FIELD__EVENT) {
YSuggestTextFieldEvents event = (YSuggestTextFieldEvents) msg.getNewValue();
if (event != null) {
doExecuteEvent(event);
}
}
}
}
@SuppressWarnings("serial")
class DialogHandleImp {
private Window window;
@SuppressWarnings("unchecked")
public void open() {
if (modelAccess.yField.getCurrentValueDTO() == null) {
return;
}
window = new Window();
window.setClosable(true);
window.setModal(true);
VerticalLayout content = new VerticalLayout();
// content.setHeight("450px");
// content.setWidth("600px");
content.setMargin(true);
content.setSpacing(true);
content.setSizeFull();
window.setContent(content);
VerticalLayout renderTarget = new VerticalLayout();
renderTarget.setMargin(true);
renderTarget.setSpacing(true);
renderTarget.setSizeFull();
content.addComponent(renderTarget);
content.setExpandRatio(renderTarget, 1.0f);
UI ui = SuggestTextFieldPresentation.this.text.getUI();
ui.addWindow(window);
Grid grid = new Grid();
grid.setHeight("450px");
grid.setWidth("600px");
grid.setSelectionMode(SelectionMode.SINGLE);
renderTarget.addComponent(grid);
renderTarget.setExpandRatio(grid, 1.0f);
IBeanSearchServiceFactory factory = getViewContext().getService(IBeanSearchServiceFactory.class.getName());
ISharedStateContext sharedState = getViewContext().getService(ISharedStateContext.class.getName());
@SuppressWarnings("rawtypes")
BeanServiceLazyLoadingContainer<?> datasource = new BeanServiceLazyLoadingContainer(
factory.createService(modelAccess.yField.getType(), true), modelAccess.yField.getType(), sharedState);
Object currentSelected = modelAccess.yField.getCurrentValueDTO();
java.lang.reflect.Field idField = DtoUtils.getIdField(currentSelected.getClass());
String idProperty = idField.getName();
String validFromProperty = "validFrom";
Object idValue = DtoUtils.getIdValue(currentSelected);
if (idValue instanceof UUIDHist) {
UUIDHist histIdValue = (UUIDHist) idValue;
idValue = histIdValue.id;
validFromProperty = idProperty + ".validFrom";
idProperty = idProperty + ".id";
}
// add the validFrom from UUIDHist as nested property
datasource.addNestedContainerProperty(validFromProperty);
Container.Filter filter = new Compare.Equal(idProperty, idValue);
datasource.addGlobalContainerFilter(filter);
grid.setContainerDataSource(datasource);
java.lang.reflect.Field domainKeyField = DtoUtils.getDomainKeyField(modelAccess.yField.getType());
java.lang.reflect.Field domainDescField = DtoUtils.getDomainDescriptionField(modelAccess.yField.getType());
// prepare columns to show
//
List<String> columnsToShow = new ArrayList<>();
if (domainKeyField != null) {
columnsToShow.add(domainKeyField.getName());
}
columnsToShow.add(validFromProperty);
if (domainDescField != null) {
columnsToShow.add(domainDescField.getName());
}
columnsToShow.add("histCurrent");
grid.setColumns(columnsToShow.toArray());
Column valFromColumn = grid.getColumn(validFromProperty);
valFromColumn.setConverter(new Converter<String, Long>() {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.SSS");
@Override
public Long convertToModel(String value, Class<? extends Long> targetType, Locale locale)
throws Converter.ConversionException {
throw new IllegalStateException();
}
@Override
public String convertToPresentation(Long value, Class<? extends String> targetType, Locale locale)
throws Converter.ConversionException {
return df.format(new Date(value));
}
@Override
public Class<Long> getModelType() {
return Long.class;
}
@Override
public Class<String> getPresentationType() {
return String.class;
}
});
grid.setSortOrder(Collections.singletonList(new SortOrder(validFromProperty, SortDirection.DESCENDING)));
// create a button to use the current selection
//
NativeButton useBotton = new NativeButton("select version");
renderTarget.addComponent(useBotton);
useBotton.setEnabled(true);
renderTarget.setComponentAlignment(useBotton, Alignment.BOTTOM_RIGHT);
useBotton.addClickListener(e -> {
Object dto = grid.getSelectedRow();
internalSetLastHistorizedSuggestion(dto);
close();
});
window.setHeight("450px");
window.setWidth("600px");
window.center();
}
public void close() {
window.close();
}
}
}