GridLayout , and then when you hide rows or columns in a standard Vaadin, there are empty spaces of indents for invisible components. This behavior can be changed, which will require the creation of its successor GridLayout . SuperGridLayout call it SuperGridLayout .
SuperGridLayout - the heir of the server-side GridLayoutSuperGridLayoutConnector - connector for connection of the server with the widget, the successor to the GridLayoutConnectorSuperGridLayoutWidget - the widget itself, a successor to VGridLayoutcom.vaadin.ui package. Developers add-ons are generally quite common practice, although there is progress towards extensibility.SuperGridLayout itself SuperGridLayout not contain any logic: public class SuperGridLayout extends GridLayout { } SuperGridLayoutConnector indicates that we will use the SuperGridLayoutWidget widget. Vaadin defines this by the return type of the getWidget() method. @Connect(SuperGridLayout.class) public class SuperGridLayoutConnector extends GridLayoutConnector { @Override public SuperGridLayoutWidget getWidget() { return (SuperGridLayoutWidget) super.getWidget(); } } public class SuperGridLayoutWidget extends VGridLayout { // .. @Override void layoutCellsHorizontally() { // ... for (int i = 0; i < cells.length; i++) { for (int j = 0; j < cells[i].length; j++) { // ... // Fix for GridLayout leaves an empty space for invisible components #VAADIN-12655 // hide zero width columns if (columnWidths[i] > 0) { x += columnWidths[i] + horizontalSpacing; } } // ... } @Override void layoutCellsVertically() { // ... for (int column = 0; column < cells.length; column++) { // ... for (int row = 0; row < cells[column].length; row++) { // ... // Fix for GridLayout leaves an empty space for invisible components #VAADIN-12655 // hide zero height rows if (rowHeights[row] > 0) { y += rowHeights[row] + verticalSpacing; } } } // ... } } SuperTree , SuperTreeWidget and SuperTreeConnector . SuperTree is a simple heir to Tree. And in SuperTreeWidget will completely copy the code from VTree , into SuperTreeConnector - the code from TreeConnector . Next, change the code in the SuperTreeConnector so that it uses the SuperTreeWiget widget and the @Connect(SuperTree.class) annotation @Connect(SuperTree.class) .SuperTreeConnector we SuperTreeConnector turn on the contextMenuSelection flag and accessors for it. In the updateFromUIDL method with the flag set, we will reset the flag for the widget with the flag rendering = false and interrupt the execution. This is necessary so that our context menu is not minimized. Next, in the SuperTreeWidget.TreeNode add a showContextMenu selection to the showContextMenu method if it is not selected: public void showContextMenu(Event event) { if (!readonly && !disabled) { // Select node by right click if (!isSelected()) { toggleSelection(); getConnector().setContextMenuSelection(true); } if (actionKeys != null) { int left = event.getClientX(); int top = event.getClientY(); top += Window.getScrollTop(); left += Window.getScrollLeft(); client.getContextMenu().showAt(this, left, top); } event.stopPropagation(); event.preventDefault(); } } 
Panel , Window or UI objects. This means that adding leafers for hotkeys, for example, for a field, you add them to the guardian container nearest the hierarchy. This behavior leads to the fact that for the same keys in the two fields you already need to write clever code, and the writing of your components with hot keys is complicated by an order of magnitude. If we simply wrap all duplicate components in the panel, then we will complicate our browser screen.
SuperTextField with a search for Enter and the ability to use several such fields on the screen.SuperTextField we define our ActionManager responsible for the hotkeys of this field. public class SuperTextField extends TextField implements Action.Container { //.. /** * Keeps track of the Actions added to this component, and manages the * painting and handling as well. */ protected ActionManager shortcutsManager; @Override public void paintContent(PaintTarget target) throws PaintException { super.paintContent(target); if (shortcutsManager != null) { shortcutsManager.paintActions(null, target); } } @Override protected ActionManager getActionManager() { if (shortcutsManager == null) { shortcutsManager = new ConnectorActionManager(this); } return shortcutsManager; } @Override public void changeVariables(Object source, Map<String, Object> variables) { super.changeVariables(source, variables); if (shortcutsManager != null) { shortcutsManager.handleActions(variables, this); } } @Override public void addShortcutListener(ShortcutListener listener) { getActionManager().addAction(listener); } @Override public void removeShortcutListener(ShortcutListener listener) { getActionManager().removeAction(listener); } @Override public void addActionHandler(Action.Handler actionHandler) { getActionManager().addActionHandler(actionHandler); } @Override public void removeActionHandler(Action.Handler actionHandler) { getActionManager().removeActionHandler(actionHandler); } } SuperTextFieldConnector add the loading of hot keys from JSON and transfer them to the widget. @Connect(SuperTextField.class) public class SuperTextFieldConnector extends TextFieldConnector { @Override public SuperTextFieldWidget getWidget() { return (SuperTextFieldWidget) super.getWidget(); } @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { super.updateFromUIDL(uidl, client); // We may have actions attached to this text field if (uidl.getChildCount() > 0) { final int cnt = uidl.getChildCount(); for (int i = 0; i < cnt; i++) { UIDL childUidl = uidl.getChildUIDL(i); if (childUidl.getTag().equals("actions")) { if (getWidget().getShortcutActionHandler() == null) { getWidget().setShortcutActionHandler(new ShortcutActionHandler(uidl.getId(), client)); } getWidget().getShortcutActionHandler().updateActionMap(childUidl); } } } } } public class SuperTextFieldWidget extends VTextField implements ShortcutActionHandler.ShortcutActionHandlerOwner { protected ShortcutActionHandler shortcutHandler; public SuperTextFieldWidget() { // handle shortcuts DOM.sinkEvents(getElement(), Event.ONKEYDOWN); } @Override public void onBrowserEvent(Event event) { super.onBrowserEvent(event); final int type = DOM.eventGetType(event); if (type == Event.ONKEYDOWN && shortcutHandler != null) { shortcutHandler.handleKeyboardEvent(event); } } public void setShortcutActionHandler(ShortcutActionHandler handler) { this.shortcutHandler = handler; } @Override public ShortcutActionHandler getShortcutActionHandler() { return shortcutHandler; } //.. } SuperTextField as many SuperTextField fields with the same key combinations.FocusTree , FocusTreeConnector and FocusTreeWidget . public class FocusTreeWidget extends VTree { @Override public void onFocus(FocusEvent event) { super.onFocus(event); addStyleDependentName("focus"); } @Override public void onBlur(BlurEvent event) { super.onBlur(event); removeStyleDependentName("focus"); } } 

IndexedContainer or BeanContainer , which contains both options and a value. When you do not control the loading of data for the container, such a hack may be useful. (eg SQLContainer or self-written data sources). public class SuperBeanContainer<IDTYPE, BEANTYPE> extends BeanContainer<IDTYPE, BEANTYPE> { protected Object missingBoxValue; public SuperBeanContainer(Class<? super BEANTYPE> type) { super(type); } @Override public boolean containsId(Object itemId) { boolean containsFlag = super.containsId(itemId); if (!containsFlag) { missingBoxValue = itemId; } return true; } @Override public List getItemIds() { List<IDTYPE> itemIds = super.getItemIds(); if (missingBoxValue != null && !itemIds.contains(missingBoxValue)) { List<IDTYPE> newItemIds = new ArrayList<>(itemIds); newItemIds.add((IDTYPE) missingBoxValue); for (IDTYPE itemId : itemIds) { newItemIds.add(itemId); } itemIds = newItemIds; } return itemIds; } @Override public BeanItem<BEANTYPE> getItem(Object itemId) { if (missingBoxValue == itemId) { return new BeanItem(itemId); } return super.getItem(itemId); } @Override public int size() { int size = super.size(); if (missingBoxValue != null) { size++; } return size; } } mvn clean package jetty:runSource: https://habr.com/ru/post/208388/
All Articles