// TODO: учеть версионность! void createGroupEditor(final long id, final Set<String> names) { final Organization org = AdminServiceProvider.get().findOrganizationById(id); final Set<String> all = AdminServiceProvider.get().getOrgGroupNames(); final VerticalLayout layout = new VerticalLayout(); layout.setSpacing(true); final TwinColSelect twin = new TwinColSelect(); twin.setSizeFull(); twin.setNullSelectionAllowed(true); twin.setLeftColumnCaption("Доступные"); twin.setRightColumnCaption("Отобранные для " + org.getName()); twin.setImmediate(true); for (final String name : all) { twin.addItem(name); if (names.contains(name)) { twin.select(name); } } layout.addComponent(twin); final HorizontalLayout h = new HorizontalLayout(); h.setSpacing(true); Button cancel = new Button( "Отменить", new Button.ClickListener() { private static final long serialVersionUID = -2885182304929510066L; @Override public void buttonClick(Button.ClickEvent event) { showOrganization(id); } }); cancel.setClickShortcut(KeyCode.ESCAPE, 0); Button ok = new Button( "Применить", new Button.ClickListener() { private static final long serialVersionUID = -3182280627040233669L; @Override public void buttonClick(Button.ClickEvent event) { AdminServiceProvider.get() .setOrgGroupNames( id, new TreeSet<String>((Collection<String>) twin.getValue())); showOrganization(id); } }); ok.setClickShortcut(KeyCode.O, ModifierKey.CTRL); h.addComponent(ok); h.addComponent(cancel); layout.addComponent(h); layout.setSizeFull(); panel.removeAllComponents(); panel.addComponent(layout); twin.focus(); }