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 GridLayout
SuperGridLayoutConnector
- connector for connection of the server with the widget, the successor to the GridLayoutConnector
SuperGridLayoutWidget
- the widget itself, a successor to VGridLayout
com.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:run
Source: https://habr.com/ru/post/208388/
All Articles