├── .settings
└── .gitignore
├── GridFastNavigation-demo
├── .gitignore
├── src
│ └── main
│ │ ├── webapp
│ │ ├── META-INF
│ │ │ ├── MANIFEST.MF
│ │ │ └── context.xml
│ │ └── VAADIN
│ │ │ ├── themes
│ │ │ └── demo
│ │ │ │ ├── favicon.ico
│ │ │ │ ├── images
│ │ │ │ └── radial-gradient.png
│ │ │ │ └── styles.scss
│ │ │ └── widgetsets
│ │ │ └── org.vaadin.patrik.demo.DemoWidgetSet
│ │ │ └── GridFastNavigation
│ │ │ └── styles.css
│ │ ├── java
│ │ └── org
│ │ │ └── vaadin
│ │ │ └── patrik
│ │ │ └── demo
│ │ │ ├── MessageLog.java
│ │ │ ├── ServerMessage.java
│ │ │ ├── MessageGrid.java
│ │ │ ├── DemoColumns.java
│ │ │ ├── DemoUI.java
│ │ │ └── DemoFastGrid.java
│ │ └── resources
│ │ └── org
│ │ └── vaadin
│ │ └── patrik
│ │ └── demo
│ │ └── DemoWidgetSet.gwt.xml
├── .settings
│ └── .gitignore
└── pom.xml
├── .gitignore
├── GridFastNavigation-addon
├── src
│ └── main
│ │ ├── resources
│ │ └── org
│ │ │ └── vaadin
│ │ │ └── patrik
│ │ │ ├── public
│ │ │ └── GridFastNavigation
│ │ │ │ └── styles.css
│ │ │ └── GridFastNavigationWidgetSet.gwt.xml
│ │ └── java
│ │ └── org
│ │ └── vaadin
│ │ └── patrik
│ │ ├── shared
│ │ ├── DeleteButtonRendererServerRpc.java
│ │ ├── DeleteButtonRendererState.java
│ │ ├── FastNavigationClientRPC.java
│ │ ├── FastNavigationServerRPC.java
│ │ └── FastNavigationState.java
│ │ ├── events
│ │ ├── Listener.java
│ │ ├── ClickOutEvent.java
│ │ ├── EventListenerList.java
│ │ ├── RowEditEvent.java
│ │ ├── RowFocusEvent.java
│ │ ├── EditorCloseEvent.java
│ │ ├── CellEditEvent.java
│ │ ├── CellFocusEvent.java
│ │ └── EditorOpenEvent.java
│ │ ├── client
│ │ ├── RPCLock.java
│ │ ├── SpinLock.java
│ │ ├── FocusTracker.java
│ │ ├── GridViolators.java
│ │ ├── Keys.java
│ │ ├── DeleteButtonRendererConnector.java
│ │ ├── GridFastNavigationConnector.java
│ │ └── EditorWidgets.java
│ │ ├── helper
│ │ └── OffsetHelper.java
│ │ ├── DeleteButtonRenderer.java
│ │ └── FastNavigation.java
├── .settings
│ └── .gitignore
├── assembly
│ ├── MANIFEST.MF
│ └── assembly.xml
└── pom.xml
├── pom.xml
├── LICENSE.txt
└── README.md
/.settings/.gitignore:
--------------------------------------------------------------------------------
1 | /org.eclipse.m2e.core.prefs
2 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.classpath
3 | /.project
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.project
2 | GridFastNavigation-demo/src/main/webapp/VAADIN/widgetsets/
3 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Class-Path:
3 |
4 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/VAADIN/themes/demo/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TatuLund/GridFastNavigation/HEAD/GridFastNavigation-demo/src/main/webapp/VAADIN/themes/demo/favicon.ico
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/MessageLog.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | public interface MessageLog
4 | {
5 |
6 | void writeOutput(String string);
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/VAADIN/themes/demo/images/radial-gradient.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/TatuLund/GridFastNavigation/HEAD/GridFastNavigation-demo/src/main/webapp/VAADIN/themes/demo/images/radial-gradient.png
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/resources/org/vaadin/patrik/public/GridFastNavigation/styles.css:
--------------------------------------------------------------------------------
1 | div.GridFastNavigation {
2 | cursor: pointer;
3 | user-select: none;
4 | -webkit-user-select: none;
5 | -moz-user-select: none;
6 | -ms-user-select: none;
7 | }
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/VAADIN/widgetsets/org.vaadin.patrik.demo.DemoWidgetSet/GridFastNavigation/styles.css:
--------------------------------------------------------------------------------
1 | div.GridFastNavigation {
2 | cursor: pointer;
3 | user-select: none;
4 | -webkit-user-select: none;
5 | -moz-user-select: none;
6 | -ms-user-select: none;
7 | }
--------------------------------------------------------------------------------
/GridFastNavigation-addon/.settings/.gitignore:
--------------------------------------------------------------------------------
1 | /org.eclipse.core.resources.prefs
2 | /org.eclipse.jdt.core.prefs
3 | /org.eclipse.m2e.core.prefs
4 | /org.eclipse.wst.common.component
5 | /org.eclipse.wst.common.project.facet.core.xml
6 | /org.eclipse.wst.validation.prefs
7 | /com.vaadin.integration.eclipse.prefs
8 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/assembly/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Vaadin-Package-Version: 1
3 | Vaadin-Addon: ${Vaadin-Addon}
4 | Vaadin-License-Title: ${Vaadin-License-Title}
5 | Implementation-Vendor: ${Implementation-Vendor}
6 | Implementation-Title: ${Implementation-Title}
7 | Implementation-Version: ${Implementation-Version}
8 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/shared/DeleteButtonRendererServerRpc.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.shared;
2 |
3 | import com.vaadin.shared.MouseEventDetails;
4 | import com.vaadin.shared.communication.ServerRpc;
5 |
6 | public interface DeleteButtonRendererServerRpc extends ServerRpc {
7 |
8 | public void onClick(String rowKey, MouseEventDetails mouseEventDetails);
9 | }
10 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/.settings/.gitignore:
--------------------------------------------------------------------------------
1 | /.jsdtscope
2 | /org.eclipse.core.resources.prefs
3 | /org.eclipse.jdt.core.prefs
4 | /org.eclipse.m2e.core.prefs
5 | /org.eclipse.wst.common.component
6 | /org.eclipse.wst.common.project.facet.core.xml
7 | /org.eclipse.wst.jsdt.ui.superType.container
8 | /org.eclipse.wst.jsdt.ui.superType.name
9 | /org.eclipse.wst.validation.prefs
10 | /com.vaadin.integration.eclipse.prefs
11 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/shared/DeleteButtonRendererState.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.shared;
2 |
3 | import com.vaadin.shared.ui.grid.renderers.ClickableRendererState;
4 |
5 | public class DeleteButtonRendererState extends ClickableRendererState {
6 | public boolean htmlContentAllowed = false;
7 | public String delete = "Delete";
8 | public String confirm = "Confirm";
9 | }
10 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/Listener.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.event.SerializableEventListener;
4 |
5 | /**
6 | * Supertype of the Listeners used in {@link org.vaadin.patrik.FastNavigation}
7 | *
8 | * @param Type of the Event
9 | */
10 | public interface Listener extends SerializableEventListener {
11 | public void onEvent(EventType event);
12 | }
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/resources/org/vaadin/patrik/GridFastNavigationWidgetSet.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/ClickOutEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 |
5 | /**
6 | * ClickOutEvent is emitted when user clicks outside the Grid.
7 | *
8 | * @since 2.1.8
9 | *
10 | * @see org.vaadin.patrik.FastNavigation#FastNavigation(com.vaadin.ui.Grid, boolean, boolean)
11 | * @see org.vaadin.patrik.FastNavigation#addClickOutListener(org.vaadin.patrik.FastNavigation.ClickOutListener)
12 | *
13 | */
14 | public class ClickOutEvent extends Component.Event {
15 |
16 | public ClickOutEvent(Component source) {
17 | super(source);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/shared/FastNavigationClientRPC.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.shared;
2 |
3 | import java.util.List;
4 |
5 | import com.vaadin.shared.communication.ClientRpc;
6 |
7 | /**
8 | * Server-to-client RPC methods
9 | */
10 | public interface FastNavigationClientRPC extends ClientRpc {
11 |
12 | void setDisabledColumns(List indices);
13 |
14 | void unlockEditor(int lockId);
15 |
16 | void validationHasErrors();
17 |
18 | void setFocusedCell(int row, int col, boolean wait);
19 |
20 | void closeEditor();
21 |
22 | void editRow(int rowIndex, int columnIndexDOM);
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/RPCLock.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | public class RPCLock {
7 |
8 | private Set locks;
9 | private int seq;
10 |
11 | public RPCLock() {
12 | locks = new HashSet();
13 | seq = 1;
14 | }
15 |
16 | int requestLock() {
17 | locks.add(seq);
18 | return seq++;
19 | }
20 |
21 | void releaseLock(int id) {
22 | locks.remove(id);
23 | }
24 |
25 | void clearLocks() {
26 | locks.clear();
27 | }
28 |
29 | boolean isLocked() {
30 | return !locks.isEmpty();
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/shared/FastNavigationServerRPC.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.shared;
2 |
3 | import com.vaadin.shared.communication.ServerRpc;
4 |
5 | /**
6 | * Client-to-server RPC methods
7 | */
8 | public interface FastNavigationServerRPC extends ServerRpc {
9 |
10 | void focusUpdated(int rowIndex, int colIndex, boolean isUserOriginated);
11 |
12 | void rowUpdated(int rowIndex, boolean moved);
13 |
14 | void cellUpdated(int rowIndex, int colIndex, String newData, String oldData, boolean moved);
15 |
16 | void editorOpened(int rowIndex, int colIndex, int lockId, int keyCode, boolean isUserOriginated);
17 |
18 | void editorClosed(int rowIndex, int colIndex, boolean wasCancelled);
19 |
20 | void clickOut();
21 |
22 | void ping();
23 |
24 | void forceValidate(boolean move);
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/resources/org/vaadin/patrik/demo/DemoWidgetSet.gwt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/EventListenerList.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import java.io.Serializable;
4 | import java.util.ArrayList;
5 | import java.util.List;
6 |
7 | /**
8 | * Used in {@link org.vaadin.patrik.FastNavigation} for listener maintenance
9 | *
10 | * @param Listener type
11 | * @param Event type
12 | */
13 | public class EventListenerList, EVENT> implements Serializable {
14 | private final List listeners;
15 |
16 | public EventListenerList() {
17 | listeners = new ArrayList();
18 | }
19 |
20 | public void addListener(LISTENER l) {
21 | listeners.add(l);
22 | }
23 |
24 | public void removeListener(LISTENER l) {
25 | listeners.remove(l);
26 | }
27 |
28 | public void clearListeners() {
29 | listeners.clear();
30 | }
31 |
32 | public void dispatch(EVENT event) {
33 | for(LISTENER l : listeners) {
34 | l.onEvent(event);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/ServerMessage.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | public class ServerMessage
4 | {
5 | private String message;
6 |
7 | public ServerMessage(String msg)
8 | {
9 | this.message = msg;
10 | }
11 |
12 | public String getMessage()
13 | {
14 | return message;
15 | }
16 |
17 | public void setMessage(String message)
18 | {
19 | this.message = message;
20 | }
21 |
22 | @Override
23 | public String toString()
24 | {
25 | return "ServerMessage [message=" + message + "]";
26 | }
27 |
28 | @Override
29 | public int hashCode()
30 | {
31 | final int prime = 31;
32 | int result = 1;
33 | result = prime * result + ((message == null) ? 0 : message.hashCode());
34 | return result;
35 | }
36 |
37 | @Override
38 | public boolean equals(Object obj)
39 | {
40 | if (this == obj)
41 | return true;
42 | if (obj == null)
43 | return false;
44 | if (getClass() != obj.getClass())
45 | return false;
46 | ServerMessage other = (ServerMessage) obj;
47 | if (message == null)
48 | {
49 | if (other.message != null)
50 | return false;
51 | }
52 | else if (!message.equals(other.message))
53 | return false;
54 | return true;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/RowEditEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 |
5 | /**
6 | * RowEditEvent is emitted when value in the Editor has been changed
7 | *
8 | * @see org.vaadin.patrik.FastNavigation#addRowEditListener(org.vaadin.patrik.FastNavigation.RowEditListener)
9 | *
10 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
11 | */
12 | @SuppressWarnings("serial")
13 | public class RowEditEvent extends Component.Event {
14 |
15 | private int rowIndex;
16 | private T item;
17 |
18 | public RowEditEvent(Component source, Integer rowIndex, T item) {
19 | super(source);
20 | this.rowIndex = rowIndex;
21 | this.item = item;
22 | }
23 |
24 | /**
25 | * Get index of the row which was edited
26 | *
27 | * @return Index of the row which is edited
28 | */
29 | public int getRowIndex() {
30 | return rowIndex;
31 | }
32 |
33 | /**
34 | * Get item which was edited from underlying datasource
35 | *
36 | * @since 2.1.4
37 | *
38 | * @return Item which is edited
39 | */
40 | public T getItem() {
41 | return item;
42 | }
43 |
44 | }
45 |
46 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.vaadin.patrik
6 | GridFastNavigation-root
7 | pom
8 | 2.6.3
9 | GridFastNavigation Add-on Root Project
10 |
11 |
12 | GridFastNavigation-addon
13 | GridFastNavigation-demo
14 |
15 |
16 |
17 |
18 |
19 | vaadin-prerelease
20 |
21 | false
22 |
23 |
24 |
25 |
26 | vaadin-prereleases
27 | https://maven.vaadin.com/vaadin-prereleases
28 |
29 |
30 |
31 |
32 | vaadin-prereleases
33 | https://maven.vaadin.com/vaadin-prereleases
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/RowFocusEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 |
5 | /**
6 | * RowFocusEvent is emitted when focused row is changed in the Grid
7 | *
8 | * @see org.vaadin.patrik.FastNavigation#addRowFocusListener(org.vaadin.patrik.FastNavigation.RowFocusListener)
9 | *
10 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
11 | */
12 | @SuppressWarnings("serial")
13 | public class RowFocusEvent extends Component.Event {
14 |
15 | private int row;
16 | private T item;
17 |
18 | public RowFocusEvent(Component source, int rowIndex, T item) {
19 | super(source);
20 | this.row = rowIndex;
21 | this.item = item;
22 | }
23 |
24 | /**
25 | * Get index of the row which was edited
26 | *
27 | * @return Index of the row which is edited, -1 if focus in Header/Footer
28 | */
29 | public int getRow() {
30 | return row;
31 | }
32 |
33 | /**
34 | * Get item which wherew focus is from underlying datasource
35 | *
36 | * @since 2.1.5
37 | *
38 | * @return item where focus is, null if focus in Header/Footer
39 | */
40 | public T getItem() {
41 | return item;
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/SpinLock.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import com.google.gwt.animation.client.AnimationScheduler;
4 | import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
5 |
6 | /**
7 | * Perform asynchronous spinlocking through RequestAnimationFrame
8 | */
9 | public class SpinLock {
10 |
11 | /**
12 | * LockFunction interface: single function, should return 'true' as long
13 | * as lock is to be held, and 'false' when it should be released
14 | */
15 | public interface LockFunction {
16 | boolean execute();
17 | }
18 |
19 | /**
20 | * Callback function gets called when the lock is released.
21 | */
22 | public interface Callback {
23 | void complete();
24 | }
25 |
26 | public static void lock(final LockFunction fn, final Callback cb) {
27 | final AnimationCallback a = new AnimationCallback() {
28 | @Override
29 | public void execute(double timestamp) {
30 | if(fn.execute()) {
31 | AnimationScheduler.get().requestAnimationFrame(this);
32 | } else {
33 | cb.complete();
34 | }
35 | }
36 | };
37 | AnimationScheduler.get().requestAnimationFrame(a);
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/assembly/assembly.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | addon
7 |
8 |
10 |
11 |
12 | zip
13 |
14 |
15 |
16 | false
17 |
18 |
19 |
20 | ..
21 |
22 | LICENSE.txt
23 | README.md
24 |
25 |
26 |
27 | target
28 |
29 |
30 | *.jar
31 | *.pdf
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | assembly/MANIFEST.MF
40 | META-INF
41 | true
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/helper/OffsetHelper.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.helper;
2 |
3 | import java.io.Serializable;
4 |
5 | import com.vaadin.ui.Grid;
6 | import com.vaadin.ui.components.grid.GridSelectionModel;
7 | import com.vaadin.ui.components.grid.MultiSelectionModel;
8 |
9 | /**
10 | * Helps in calculation the offset for the columns in an EditorOpenEvent.
11 | *
12 | * @since 2.3.10
13 | */
14 | public class OffsetHelper implements Serializable {
15 |
16 | /**
17 | * Calculates offset needed e.g. in multiselect mode it needs to be 1. Override this
18 | * method if you want to implement custom OffsetHelper by extending this class and
19 | * set it with {@link org.vaadin.patrik.FastNavigation#setOffsetHelper(OffsetHelper)}
20 | *
21 | * @since 2.3.10
22 | *
23 | * @param g Grid
24 | * @return Offset
25 | */
26 | public int calculateOffset(final Grid> g) {
27 | int offset = 0;
28 | GridSelectionModel> selectionModel = g.getSelectionModel();
29 | if (selectionModel instanceof MultiSelectionModel
30 | && !this.isGridExtensionPackTableSelectionModel(selectionModel)) {
31 | offset = 1;
32 | }
33 | return offset;
34 | }
35 |
36 | /*
37 | * Offset for GridExpansionPack needs to be zero in MultiselectionMode.
38 | */
39 | private boolean isGridExtensionPackTableSelectionModel(GridSelectionModel> selectionModel) {
40 | return selectionModel.getClass().getName()
41 | .equals("org.vaadin.teemusa.gridextensions.tableselection.TableSelectionModel");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/MessageGrid.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.vaadin.data.provider.ListDataProvider;
7 | import com.vaadin.ui.Grid;
8 | import com.vaadin.ui.UI;
9 |
10 | public class MessageGrid extends Grid implements MessageLog
11 | {
12 | private static final long serialVersionUID = 1L;
13 |
14 |
15 | private static final int MAX_MESSAGES = 50;
16 |
17 |
18 | List messageList;
19 | ListDataProvider messageData;
20 |
21 | MessageGrid()
22 | {
23 | super("Message Log");
24 |
25 | messageList = new ArrayList<>();
26 | messageData = new ListDataProvider(messageList);
27 |
28 | this.getHeaderRow(0).setStyleName("my-background");
29 |
30 | this.setDataProvider(messageData);
31 | this.addColumn(ServerMessage::getMessage).setCaption("Message").setExpandRatio(1);
32 | this.setSizeFull();
33 | }
34 |
35 | public void writeOutput(final String msg)
36 | {
37 | UI.getCurrent().access(new Runnable()
38 | {
39 | @Override
40 | public void run()
41 | {
42 | while (messageData.getItems().size() >= MAX_MESSAGES)
43 | {
44 | messageList.remove(0);
45 | messageData.refreshAll();
46 | }
47 |
48 | ServerMessage message = new ServerMessage(msg);
49 | messageList.add(message);
50 | messageData.refreshAll();
51 | scrollTo(messageList.size() - 1);
52 | }
53 | });
54 | }
55 |
56 | public void clear()
57 | {
58 | messageList.clear();
59 | messageData.refreshAll();
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/shared/FastNavigationState.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.shared;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | import com.vaadin.shared.communication.SharedState;
7 |
8 | @SuppressWarnings("serial")
9 | public class FastNavigationState extends SharedState {
10 |
11 | public boolean openEditorOnType = true;
12 |
13 | public boolean selectTextOnEditorOpen = true;
14 |
15 | public boolean allowTabRowChange = true;
16 |
17 | public boolean allowArrowRowChange = true;
18 |
19 | public boolean changeColumnAfterLastRow = false;
20 |
21 | public boolean hasFocusListener = false;
22 |
23 | public boolean hasRowFocusListener = false;
24 |
25 | public boolean hasCellFocusListener = false;
26 |
27 | public boolean hasRowEditListener = false;
28 |
29 | public boolean hasCellEditListener = false;
30 |
31 | public boolean hasEditorOpenListener = false;
32 |
33 | public boolean hasEditorMoveListener = false;
34 |
35 | public boolean hasEditorCloseListener = false;
36 |
37 | public boolean hasClickOutListener = false;
38 |
39 | public boolean changeColumnOnEnter = false;
40 |
41 | public boolean openEditorWithSingleClick = true;
42 |
43 | public boolean dispatchEditEventOnBlur = false;
44 |
45 | public boolean saveWithCtrlS = false;
46 |
47 | public boolean rowValidation = false;
48 |
49 | public boolean homeEndEnabled = true;
50 |
51 | public boolean enableSelectedStyle = false;
52 |
53 | public Set openShortcuts = new HashSet();
54 |
55 | public Set closeShortcuts = new HashSet();
56 |
57 | public Set saveShortcuts = new HashSet();
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/EditorCloseEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 | import com.vaadin.ui.Grid;
5 | import com.vaadin.ui.components.grid.MultiSelectionModel;
6 |
7 | /**
8 | * EditorCloseEvent is emitted when Editor is closed
9 | *
10 | * @see org.vaadin.patrik.FastNavigation#addEditorCloseListener(org.vaadin.patrik.FastNavigation.EditorCloseListener)
11 | *
12 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
13 | */
14 | @SuppressWarnings("serial")
15 | public class EditorCloseEvent extends Component.Event {
16 |
17 | private boolean cancelled;
18 | private int rowIndex;
19 | private int colIndex;
20 | private int offset = 0;
21 |
22 | public EditorCloseEvent(Component source, int row, int col, boolean cancel) {
23 | super(source);
24 | rowIndex = row;
25 | colIndex = col;
26 | cancelled = cancel;
27 | Grid grid = (Grid) source;
28 | if (grid.getSelectionModel() instanceof MultiSelectionModel) offset = 1;
29 | }
30 |
31 | /**
32 | * Was editor cancelled = true or saved = false
33 | *
34 | * @return true if editor was cancelled
35 | */
36 | public boolean wasCancelled() {
37 | return cancelled;
38 | }
39 |
40 | /**
41 | * Get index of the column where editor was closed
42 | *
43 | * @return Index of the column where editor was closed
44 | */
45 | public int getRow() {
46 | return rowIndex;
47 | }
48 |
49 | /**
50 | * Get index of the column where editor was closed
51 | *
52 | * @return Index of the column where editor was closed
53 | */
54 | public int getColumnIndex() {
55 | return colIndex-offset;
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/webapp/VAADIN/themes/demo/styles.scss:
--------------------------------------------------------------------------------
1 | @import "../valo/valo.scss";
2 |
3 | $gray: #d1d1cf;
4 | $green: #40b527;
5 | $darkgreen: darken($green, 30%);
6 | // $v-grid-row-stripe-background-color: $v-grid-row-background-color !default;
7 | $v-grid-header-background-color: #20a020;
8 |
9 | // Prefix all selectors in your theme with .demo
10 | .demo {
11 |
12 | // Include valo theme styles in your theme
13 | @include valo;
14 |
15 | // You can style your demo app right here
16 | .demoContentLayout {
17 | background-color: $gray;
18 | background-image: url(images/radial-gradient.png);
19 | background-size: 90%;
20 | background-position: center center;
21 | background-repeat: no-repeat;
22 | }
23 |
24 |
25 | .v-grid-row.red > td {
26 | color: red;
27 | }
28 |
29 | .v-grid-editor-cells {
30 | .not-editable {
31 | color: white !important;
32 | .v-textfield {
33 | display: none;
34 | }
35 | .v-datefield {
36 | display: none;
37 | }
38 | .v-checkbox {
39 | display: none;
40 | }
41 | .v-filterselect {
42 | display: none;
43 | }
44 | }
45 | }
46 |
47 | .v-grid {
48 | .v-grid-row-selected > td {
49 | color: black !important;
50 | background: yellow !important;
51 | }
52 | .v-grid-editor-selected {
53 | div {
54 | color: black !important;
55 | background: yellow !important;
56 | }
57 | }
58 | }
59 |
60 | .row-edit-disabled > td {
61 | pointer-events: none;
62 | }
63 |
64 | .my-background {
65 | background-color: blue;
66 | color: white;
67 | font-weight: bold;
68 | }
69 |
70 | // You can also customize your component for the demo
71 | // app, but remember that these styles are not part of
72 | // the component. To include built-in CSS for your component,
73 | // edit client/styles.css under java sources
74 | div.GridFastNavigation {
75 | color: $green;
76 | font-size: 50pt;
77 | font-weight: bold;
78 | text-shadow: 0px 3px 0px $darkgreen,
79 | 0px 14px 10px rgba(0,0,0,0.15),
80 | 0px 24px 2px rgba(0,0,0,0.1),
81 | 0px 34px 30px rgba(0,0,0,0.1);
82 | text-align: center;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/CellEditEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 | import com.vaadin.ui.Grid;
5 |
6 | /**
7 | * CellEditEvent is emitted when value in the Editor has been changed
8 | *
9 | * @see org.vaadin.patrik.FastNavigation#addCellEditListener(org.vaadin.patrik.FastNavigation.CellEditListener)
10 | *
11 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
12 | */
13 | @SuppressWarnings("serial")
14 | public class CellEditEvent extends Component.Event {
15 |
16 | private int rowIndex;
17 | private int colIndex;
18 |
19 | private String oldData;
20 | private String newData;
21 | private T item;
22 |
23 | public CellEditEvent(Component source, Integer rowIndex, Integer colIndex, String newData, String oldData, T item) {
24 | super(source);
25 | this.rowIndex = rowIndex;
26 | this.colIndex = colIndex;
27 | this.newData = newData;
28 | this.oldData = oldData;
29 | this.item = item;
30 | Grid grid = (Grid) source;
31 | }
32 |
33 | /**
34 | * Get index of the column which was edited
35 | *
36 | * @return Index of the column which is edited
37 | */
38 | public int getColumnIndex() {
39 | return colIndex;
40 | }
41 |
42 | /**
43 | * Get old value as string from the Editor
44 | *
45 | * @return Old value as string from the Editor
46 | */
47 | public String getOldData() {
48 | return oldData;
49 | }
50 |
51 | /**
52 | * Get edited value as string from the Editor
53 | *
54 | * @return Edited value as string from the Editor
55 | */
56 | public String getNewData() {
57 | return newData;
58 | }
59 |
60 | /**
61 | * Get index of the row which was edited
62 | *
63 | * @return Index of the row which is edited
64 | */
65 | public int getRowIndex() {
66 | return rowIndex;
67 | }
68 |
69 | /**
70 | * Get item which was edited from underlying datasource
71 | *
72 | * @since 2.1.4
73 | *
74 | * @return Item which is edited
75 | */
76 | public T getItem() {
77 | return item;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/DemoColumns.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | import java.util.Date;
4 | import java.util.Random;
5 |
6 | public class DemoColumns
7 | {
8 | private static int row = 0;
9 | private String col1;
10 | private String col2;
11 | private Integer col3;
12 | private Double col4;
13 | private Integer col5;
14 | private Integer col6;
15 | private Date col7; // datetime
16 | private Date col8;
17 | private Boolean col9;
18 | private String col10;
19 |
20 | Random rand = new Random();
21 |
22 | DemoColumns()
23 | {
24 | col1 = "string 1 " + row;
25 | col2 = "string 2 " + row;
26 | col3 = rand.nextInt(row + 10);
27 | col4 = (double)rand.nextInt(row + 10);
28 | col5 = rand.nextInt(row + 10);
29 | col6 = rand.nextInt(row + 10);
30 | col7 = new Date();
31 | col8 = new Date();
32 | col9 = false;
33 | col10 = "medium";
34 |
35 | row++;
36 | }
37 |
38 |
39 | public String getCol1()
40 | {
41 | return col1;
42 | }
43 | public void setCol1(String col1)
44 | {
45 | this.col1 = col1;
46 | }
47 | public String getCol2()
48 | {
49 | return col2;
50 | }
51 | public void setCol2(String col2)
52 | {
53 | this.col2 = col2;
54 | }
55 | public Integer getCol3()
56 | {
57 | return col3;
58 | }
59 | public void setCol3(Integer col3)
60 | {
61 | this.col3 = col3;
62 | }
63 | public Double getCol4()
64 | {
65 | return col4;
66 | }
67 | public void setCol4(Double col4)
68 | {
69 | this.col4 = col4;
70 | }
71 | public Integer getCol5()
72 | {
73 | return col5;
74 | }
75 | public void setCol5(Integer col5)
76 | {
77 | this.col5 = col5;
78 | }
79 | public Integer getCol6()
80 | {
81 | return col6;
82 | }
83 | public void setCol6(Integer col6)
84 | {
85 | this.col6 = col6;
86 | }
87 | public Date getCol7()
88 | {
89 | return col7;
90 | }
91 | public void setCol7(Date col7)
92 | {
93 | this.col7 = col7;
94 | }
95 | public Date getCol8()
96 | {
97 | return col8;
98 | }
99 | public void setCol8(Date col8)
100 | {
101 | this.col8 = col8;
102 | }
103 | public Boolean getCol9()
104 | {
105 | return col9;
106 | }
107 | public void setCol9(Boolean col9)
108 | {
109 | this.col9 = col9;
110 | }
111 | public String getCol10()
112 | {
113 | return col10;
114 | }
115 | public void setCol10(String col10)
116 | {
117 | this.col10 = col10;
118 | }
119 |
120 |
121 | @Override
122 | public String toString()
123 | {
124 | return "DemoColumns [col1=" + col1 + ", col2=" + col2 + ", col3=" + col3 + ", col4=" + col4 + ", col5=" + col5
125 | + ", col6=" + col6 + ", col7=" + col7 + ", col8=" + col8 + ", col10=" + col9 + ", col10=" + col10
126 | + ", rand=" + rand + "]";
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/CellFocusEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import com.vaadin.ui.Component;
4 | import com.vaadin.ui.Grid;
5 |
6 | /**
7 | * CellFocusEvent is emitted when focused cell is changed in the Grid
8 | *
9 | * @see org.vaadin.patrik.FastNavigation#addCellFocusListener(org.vaadin.patrik.FastNavigation.CellFocusListener)
10 | * @see org.vaadin.patrik.FastNavigation#setFocusedCell(int, int)
11 | * @see org.vaadin.patrik.FastNavigation#setFocusedCell(int, int, boolean)
12 | *
13 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
14 | */
15 | @SuppressWarnings("serial")
16 | public class CellFocusEvent extends Component.Event {
17 |
18 | private int row;
19 | private int col;
20 | private boolean rowChanged;
21 | private boolean colChanged;
22 | private T item;
23 | private boolean isUserOriginated;
24 |
25 | public CellFocusEvent(Component source, int row, int col, boolean rowChanged, boolean colChanged, T item, boolean isUserOriginated) {
26 | super(source);
27 | this.row = row;
28 | this.col = col;
29 | this.item = item;
30 | this.rowChanged = rowChanged;
31 | this.colChanged = colChanged;
32 | this.isUserOriginated = isUserOriginated;
33 | Grid grid = (Grid) source;
34 | }
35 |
36 | /**
37 | * Get index of the row which was edited
38 | *
39 | * @return Index of the row which is edited, -1 if focus in Header/Footer
40 | */
41 | public int getRow() {
42 | return row;
43 | }
44 |
45 | /**
46 | * Return true if the row was changed from the previously known value
47 | *
48 | * @return boolean value
49 | */
50 | public boolean wasRowChanged() {
51 | return rowChanged;
52 | }
53 |
54 | /**
55 | * Get currently focused column index
56 | *
57 | * @return integer value
58 | */
59 | public int getColumnIndex() {
60 | return col;
61 | }
62 |
63 | /**
64 | * Return true if the column was changed from the previously known value
65 | *
66 | * @return integer value
67 | */
68 | public boolean wasColumnChanged() {
69 | return colChanged;
70 | }
71 |
72 | /**
73 | * Get item which where focus is from underlying datasource
74 | *
75 | * @since 2.1.5
76 | *
77 | * @return item where focus is, null if focus in Header/Footer
78 | */
79 | public T getItem() {
80 | return item;
81 | }
82 |
83 | /**
84 | * Returns true if focus changed via UI, false if opened via setFocusedCell method
85 | *
86 | * @see org.vaadin.patrik.FastNavigation#setFocusedCell(int, int)
87 | *
88 | * @return boolean value
89 | *
90 | * @since 2.6.0
91 | */
92 | public boolean isUserOriginated() {
93 | return isUserOriginated;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/FocusTracker.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.google.gwt.animation.client.AnimationScheduler;
7 | import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
8 | import com.google.gwt.animation.client.AnimationScheduler.AnimationHandle;
9 | import com.vaadin.client.widgets.Grid;
10 |
11 | /**
12 | * Actively track position of focus in Grid using RequestAnimationFrame
13 | */
14 | public class FocusTracker {
15 |
16 | public interface FocusListener {
17 | public void focusMoved(int currentRow, int currentCol, int lastRow,
18 | int lastCol, boolean isUserOriginated);
19 | }
20 |
21 | private List listeners;
22 | private Grid> grid;
23 | private int currentRow;
24 | private int currentCol;
25 | private int lastRow;
26 | private int lastCol;
27 | private boolean run;
28 | protected AnimationHandle handle;
29 | private boolean isUserOriginated = true;
30 |
31 | public FocusTracker(Grid> g) {
32 | this.grid = g;
33 | currentRow = GridViolators.getFocusedRow(g);
34 | currentCol = GridViolators.getFocusedCol(g);
35 | lastRow = currentRow;
36 | lastCol = currentCol;
37 | listeners = new ArrayList();
38 | run = false;
39 | }
40 |
41 | public void start() {
42 | if(!run) {
43 | run = true;
44 | updateLoop.execute(0);
45 | }
46 | }
47 |
48 | public void stop() {
49 | run = false;
50 | }
51 |
52 | public boolean isRunning() {
53 | return run;
54 | }
55 |
56 | public void reset() {
57 | currentRow = -1;
58 | currentCol = -1;
59 | notifyFocusMoved();
60 | }
61 |
62 | public void wasProgrammatic() {
63 | isUserOriginated = false;
64 | }
65 |
66 | private void notifyFocusMoved() {
67 | for (FocusListener l : listeners) {
68 | l.focusMoved(currentRow, currentCol, lastRow, lastCol, isUserOriginated);
69 | }
70 | isUserOriginated = true;
71 | }
72 |
73 | public void addListener(FocusListener l) {
74 | listeners.add(l);
75 | }
76 |
77 | public void removeListener(FocusListener l) {
78 | listeners.remove(l);
79 | }
80 |
81 | public void clearListeners() {
82 | listeners.clear();
83 | }
84 |
85 | private AnimationCallback updateLoop = new AnimationCallback() {
86 | @Override
87 | public void execute(double timestamp) {
88 |
89 | int row = GridViolators.getFocusedRow(grid);
90 | int col = GridViolators.getFocusedCol(grid);
91 |
92 | if (row != currentRow || col != currentCol) {
93 | lastRow = currentRow;
94 | currentRow = row;
95 | lastCol = currentCol;
96 | currentCol = col;
97 | notifyFocusMoved();
98 | }
99 |
100 | if (run) {
101 | handle = AnimationScheduler.get().requestAnimationFrame(updateLoop);
102 | }
103 | }
104 | };
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/GridViolators.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import java.util.Map;
4 |
5 | import com.google.gwt.dom.client.DivElement;
6 | import com.google.gwt.user.client.ui.Widget;
7 | import com.vaadin.client.widgets.Grid;
8 | import com.vaadin.client.widgets.Grid.Column;
9 | import com.vaadin.client.widgets.Grid.Editor;
10 |
11 | public class GridViolators {
12 |
13 | // ========================================================================
14 | // Violators - access Grid internals irrespective of visibility
15 | // ========================================================================
16 |
17 | public static native final boolean isEditorReallyActive(Editor> editor) /*-{
18 | var state = editor.@com.vaadin.client.widgets.Grid.Editor::state;
19 | var ordinal = state.@com.vaadin.client.widgets.Grid.Editor.State::ordinal()();
20 | return ordinal == 3;
21 | }-*/;
22 |
23 | public static native final boolean isEditorReallyClosed(Editor> editor) /*-{
24 | var state = editor.@com.vaadin.client.widgets.Grid.Editor::state;
25 | var ordinal = state.@com.vaadin.client.widgets.Grid.Editor.State::ordinal()();
26 | return ordinal == 0;
27 | }-*/;
28 |
29 | public static native final Map, Widget> getEditorColumnToWidgetMap(Editor> editor) /*-{
30 | return editor.@com.vaadin.client.widgets.Grid.Editor::columnToWidget;
31 | }-*/;
32 |
33 | public static native final int getFocusedRow(Grid> grid) /*-{
34 | var cfh = grid.@com.vaadin.client.widgets.Grid::cellFocusHandler;
35 | var row = cfh.@com.vaadin.client.widgets.Grid.CellFocusHandler::rowWithFocus;
36 | var contWithFocus= cfh.@com.vaadin.client.widgets.Grid.CellFocusHandler::containerWithFocus;
37 | var escallator = grid.@com.vaadin.client.widgets.Grid::getEscalator()();
38 | var conBody = escallator.@com.vaadin.client.widgets.Escalator::getBody()();
39 | if (contWithFocus == conBody)
40 | return row;
41 | else
42 | return -1;
43 | }-*/;
44 |
45 | public static native final int getFocusedCol(Grid> grid) /*-{
46 | var cfh = grid.@com.vaadin.client.widgets.Grid::cellFocusHandler;
47 | var cell = cfh.@com.vaadin.client.widgets.Grid.CellFocusHandler::getFocusedCell()();
48 | var col = cell.@com.vaadin.client.widget.escalator.Cell::getColumn()();
49 | return col;
50 | }-*/;
51 |
52 | public static native final int getEditorColumn(Editor> editor) /*-{
53 | return editor.@com.vaadin.client.widgets.Grid.Editor::focusedColumnIndexDOM;
54 | }-*/;
55 |
56 | public static native final void setFocusedCell(Grid> grid, int rowIndex, int columnIndexDOM) /*-{
57 | grid.@com.vaadin.client.widgets.Grid::focusCell(II)(rowIndex,columnIndexDOM);
58 | }-*/;
59 |
60 | public static native final void redrawEditor(Grid> grid) /*-{
61 | var editor = grid.@com.vaadin.client.widgets.Grid::getEditor()();
62 | editor.@com.vaadin.client.widgets.Grid.Editor::showOverlay()();
63 | }-*/;
64 |
65 | public static native final DivElement getEditorCellWrapper(Grid> grid) /*-{
66 | var editor = grid.@com.vaadin.client.widgets.Grid::getEditor()();
67 | return editor.@com.vaadin.client.widgets.Grid.Editor::cellWrapper;
68 | }-*/;
69 |
70 | public static native final DivElement getEditorOverlay(Grid> grid) /*-{
71 | var editor = grid.@com.vaadin.client.widgets.Grid::getEditor()();
72 | return editor.@com.vaadin.client.widgets.Grid.Editor::editorOverlay;
73 | }-*/;
74 |
75 | public static native final DivElement getFrozenCellWrapper(Grid> grid) /*-{
76 | var editor = grid.@com.vaadin.client.widgets.Grid::getEditor()();
77 | return editor.@com.vaadin.client.widgets.Grid.Editor::frozenCellWrapper;
78 | }-*/;
79 |
80 | public static native final DivElement getEditorErrorMessage(Grid> grid) /*-{
81 | var editor = grid.@com.vaadin.client.widgets.Grid::getEditor()();
82 | return editor.@com.vaadin.client.widgets.Grid.Editor::message;
83 | }-*/;
84 | }
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/events/EditorOpenEvent.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.events;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.vaadin.ui.Component;
7 | import com.vaadin.ui.Grid;
8 | import com.vaadin.ui.Grid.Column;
9 |
10 | /**
11 | * Event used to notify of editor being opened. Can be used
12 | * to disable some columns (in other words: make them read-only)
13 | *
14 | * @see org.vaadin.patrik.FastNavigation#addEditorOpenListener(org.vaadin.patrik.FastNavigation.EditorOpenListener)
15 | *
16 | * @param Bean type of the Grid where {@link org.vaadin.patrik.FastNavigation} is being used
17 | */
18 | @SuppressWarnings("serial")
19 | public class EditorOpenEvent extends Component.Event {
20 |
21 | private int rowIndex;
22 | private int colIndex;
23 | private T item;
24 | private Integer[] disabledCols;
25 | private Grid grid;
26 | private int keyCode;
27 | private boolean isUserOriginated;
28 |
29 | public EditorOpenEvent(Component source, int row, int col, T item, int keyCode, boolean isUserOriginated) {
30 | super(source);
31 | rowIndex = row;
32 | colIndex = col;
33 | this.item = item;
34 | this.keyCode = keyCode;
35 | this.isUserOriginated = isUserOriginated;
36 | grid = (Grid) source;
37 | }
38 |
39 | /**
40 | * Get key code of the shortcut or key that triggered the opening of the Editor.
41 | *
42 | * @return Key code or -1 if no key event was associated with this opening.
43 | *
44 | * @since 2.6.0
45 | */
46 | public int getKeyCode() {
47 | return keyCode;
48 | }
49 |
50 | /**
51 | * Get index of the row where editor was opened
52 | *
53 | * @return Index of the row where editor was opened
54 | */
55 | public int getRow() {
56 | return rowIndex;
57 | }
58 |
59 | /**
60 | * Get index of the column where editor was opened
61 | *
62 | * @return Index of the column where editor was opened
63 | */
64 | public int getColumnIndex() {
65 | return colIndex;
66 | }
67 |
68 | /**
69 | * Set additional columns that should be disable when Editor opens
70 | *
71 | * @param columns Columns to be set disabled
72 | */
73 | public void disableColumns(Integer... columns) {
74 | disabledCols = columns;
75 | for (int col : disabledCols) {
76 | if (col < 0 || col > grid.getColumns().size()) {
77 | throw new IllegalArgumentException("Column index "+col+" out of bounds");
78 | }
79 | }
80 | }
81 |
82 | /**
83 | * Set all columns disabled. Can be used for example if you want to conditionally
84 | * disable editing of a row.
85 | *
86 | * @since 2.3.2
87 | */
88 | public void disableAllColumns() {
89 | List disabled = new ArrayList<>();
90 | Integer i=0;
91 | for (Column col : grid.getColumns()) {
92 | disabled.add(i);
93 | i++;
94 | }
95 | Integer[] dis = disabled.toArray(new Integer[0]);
96 | disableColumns(dis);
97 | }
98 |
99 | /**
100 | * Returns the additional columns that should be disable when Editor opens (see: disableColumns).
101 | * This method is used internally. Note, if you have set columns non editable or disabled fields
102 | * via other API's, they are not counted.
103 | *
104 | * @return returns additional columns to be disabled
105 | */
106 | public Integer[] getDisabledColumns() {
107 | return disabledCols;
108 | }
109 |
110 | /**
111 | * Get item which was opened from underlying datasource
112 | *
113 | * @return Item which is edited
114 | */
115 | public T getItem() {
116 | return item;
117 | }
118 |
119 | /**
120 | * Returns true if opening was done via UI, false if opened via editRow method
121 | *
122 | * @return boolean value
123 | *
124 | * @since 2.6.0
125 | */
126 | public boolean isUserOriginated() {
127 | return isUserOriginated;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/Keys.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import java.util.HashSet;
4 | import java.util.Set;
5 |
6 | import com.google.gwt.event.dom.client.KeyCodes;
7 | import com.google.gwt.user.client.Event;
8 |
9 | public final class Keys {
10 | private static final Set alphaNumSet;
11 |
12 | private static final Set rowChangeKeys;
13 |
14 | private static final Set colChangeKeys;
15 |
16 | static {
17 | alphaNumSet = new HashSet();
18 |
19 | for (int i = KeyCodes.KEY_A; i <= KeyCodes.KEY_Z; i++) {
20 | alphaNumSet.add(i);
21 | }
22 | for (int i = KeyCodes.KEY_ZERO; i <= KeyCodes.KEY_NINE; i++) {
23 | alphaNumSet.add(i);
24 | }
25 | for (int i = KeyCodes.KEY_NUM_ZERO; i <= KeyCodes.KEY_NUM_NINE; i++) {
26 | alphaNumSet.add(i);
27 | }
28 |
29 | rowChangeKeys = new HashSet();
30 | rowChangeKeys.add(KeyCodes.KEY_UP);
31 | rowChangeKeys.add(KeyCodes.KEY_DOWN);
32 | rowChangeKeys.add(KeyCodes.KEY_PAGEUP);
33 | rowChangeKeys.add(KeyCodes.KEY_PAGEDOWN);
34 |
35 | colChangeKeys = new HashSet();
36 | colChangeKeys.add(KeyCodes.KEY_TAB);
37 |
38 | }
39 |
40 | public static void setEnterBehavior(boolean changeColumnByEnter) {
41 | if (changeColumnByEnter) {
42 | colChangeKeys.add(KeyCodes.KEY_ENTER);
43 | colChangeKeys.add(KeyCodes.KEY_MAC_ENTER);
44 | } else {
45 | rowChangeKeys.add(KeyCodes.KEY_ENTER);
46 | rowChangeKeys.add(KeyCodes.KEY_MAC_ENTER);
47 | }
48 | }
49 |
50 | public static int translateNumKey(int keycode) {
51 | if (keycode >= 96 && keycode <= 105) return keycode - 48;
52 | else return keycode;
53 | }
54 |
55 | public static boolean isUpDownArrowKey(int keycode) {
56 | if(keycode == KeyCodes.KEY_UP || keycode == KeyCodes.KEY_DOWN || keycode == KeyCodes.KEY_PAGEUP || keycode == KeyCodes.KEY_PAGEDOWN) {
57 | return true;
58 | }
59 | return false;
60 | }
61 |
62 | public static boolean isDelKey(int keycode) {
63 | if(keycode == KeyCodes.KEY_DELETE) {
64 | return true;
65 | }
66 | return false;
67 | }
68 |
69 | public static boolean isHomeKey(int keycode) {
70 | if(keycode == KeyCodes.KEY_HOME) {
71 | return true;
72 | }
73 | return false;
74 | }
75 |
76 | public static boolean isEndKey(int keycode) {
77 | if(keycode == KeyCodes.KEY_END) {
78 | return true;
79 | }
80 | return false;
81 | }
82 |
83 |
84 | public static boolean isSpaceKey(int keycode) {
85 | if (keycode == KeyCodes.KEY_SPACE) {
86 | return true;
87 | }
88 | return false;
89 | }
90 |
91 | /**
92 | * Test if keycode is one of the alpha numeric keys [0-9a-zA-Z]
93 | *
94 | * @param keyCode Key code to be tested
95 | * @return true if key is alphanumeric
96 | */
97 | public static boolean isAlphaNumericKey(int keyCode) {
98 | return alphaNumSet.contains(keyCode);
99 | }
100 |
101 | /**
102 | * Test if keycode is defined as a row change key
103 | *
104 | * @param keyCode Key code to be tested
105 | * @return true if key is one of the row change keys
106 | */
107 | public static boolean isRowChangeKey(int keyCode) {
108 | return rowChangeKeys.contains(keyCode);
109 | }
110 |
111 | /**
112 | * Test if keycode is defined as a column change key
113 | *
114 | * @param keyCode Key code to be tested
115 | * @return true if key is one of the column change keys
116 | */
117 | public static boolean isColumnChangeKey(int keyCode) {
118 | return colChangeKeys.contains(keyCode);
119 | }
120 |
121 |
122 | /**
123 | * Test if key event contained a mofifier key (i.e. Ctrl, Shift or Alt)
124 | *
125 | * @param event DOM Event
126 | * @return true if key event contained modifier key
127 | */
128 | public static boolean isModifierKey(Event event) {
129 | return event.getShiftKey() || event.getCtrlKey() || event.getAltKey();
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/DeleteButtonRendererConnector.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import org.vaadin.patrik.shared.DeleteButtonRendererServerRpc;
4 | import org.vaadin.patrik.shared.DeleteButtonRendererState;
5 |
6 | import com.google.gwt.core.shared.GWT;
7 | import com.google.gwt.dom.client.Element;
8 | import com.google.gwt.event.dom.client.ClickEvent;
9 | import com.google.gwt.event.dom.client.ClickHandler;
10 | import com.google.gwt.event.shared.HandlerRegistration;
11 | import com.google.gwt.user.client.Timer;
12 | import com.google.gwt.user.client.ui.Button;
13 | import com.vaadin.client.MouseEventDetailsBuilder;
14 | import com.vaadin.client.communication.RpcProxy;
15 | import com.vaadin.client.communication.StateChangeEvent;
16 | import com.vaadin.client.connectors.ClickableRendererConnector;
17 | import com.vaadin.client.renderers.ClickableRenderer;
18 | import com.vaadin.client.renderers.ClickableRenderer.RendererClickHandler;
19 | import com.vaadin.client.renderers.Renderer;
20 | import com.vaadin.client.widget.grid.RendererCellReference;
21 | import com.vaadin.shared.MouseEventDetails;
22 | import com.vaadin.shared.ui.Connect;
23 |
24 | import elemental.json.JsonObject;
25 |
26 | @Connect(org.vaadin.patrik.DeleteButtonRenderer.class)
27 | public class DeleteButtonRendererConnector extends ClickableRendererConnector {
28 | DeleteButtonRendererServerRpc rpc = RpcProxy.create(DeleteButtonRendererServerRpc.class, this);
29 |
30 | public class DeleteButtonClientRenderer extends ClickableRenderer {
31 |
32 | private boolean htmlContentAllowed = false;
33 |
34 | @Override
35 | public Button createWidget() {
36 | Button b = GWT.create(Button.class);
37 |
38 | b.addClickHandler(new ClickHandler() {
39 | @Override
40 | public void onClick(ClickEvent event) {
41 | Timer t = null;
42 | String style = b.getStyleName();
43 | if (style != null && style.contains("delete-confirm")) {
44 | // If button is in cofirmed state, timer needs to be stopped
45 | // and click event needs to be emitted
46 | if (t != null) t.cancel();
47 | b.removeStyleName("delete-confirm");
48 | if (htmlContentAllowed) {
49 | b.setHTML(getState().delete);
50 | } else {
51 | b.setText(getState().delete);
52 | }
53 | MouseEventDetails mouseEventDetails = MouseEventDetailsBuilder
54 | .buildMouseEventDetails(event.getNativeEvent(),
55 | b.getElement());
56 | Element e = b.getElement();
57 | rpc.onClick(e.getPropertyString("rowKey"),mouseEventDetails);
58 | } else {
59 | // At first click we change button to confirm mode,
60 | // change text accordingly and add style name, so
61 | // that accent can be defined in theme
62 | if (htmlContentAllowed) {
63 | b.setHTML(getState().confirm);
64 | } else {
65 | b.setText(getState().confirm);
66 | }
67 | b.setStyleName("delete-confirm");
68 | // Set timer 10 sec, if not clicked by then, go
69 | // back to normal mode
70 | t = new Timer() {
71 | @Override
72 | public void run() {
73 | b.removeStyleName("delete-confirm");
74 | if (htmlContentAllowed) {
75 | b.setHTML(getState().delete);
76 | } else {
77 | b.setText(getState().delete);
78 | }
79 | Element e = b.getElement();
80 | }
81 | };
82 | t.schedule(10000);
83 | }
84 | event.stopPropagation();
85 | }
86 | });
87 | b.setStylePrimaryName("v-nativebutton");
88 | return b;
89 | }
90 |
91 | public void setHtmlContentAllowed(boolean htmlContentAllowed) {
92 | this.htmlContentAllowed = htmlContentAllowed;
93 | }
94 |
95 | public boolean isHtmlContentAllowed() {
96 | return htmlContentAllowed;
97 | }
98 |
99 | @Override
100 | public void render(RendererCellReference cell, Boolean enable, Button button) {
101 |
102 | Element e = button.getElement();
103 |
104 | if(e.getPropertyString("rowKey") != getRowKey((JsonObject) cell.getRow())) {
105 | e.setPropertyString("rowKey",
106 | getRowKey((JsonObject) cell.getRow()));
107 | }
108 |
109 | String style = button.getStyleName();
110 | if (style != null && style.contains("delete-confirm")) {
111 | button.removeStyleName("delete-confirm");
112 | }
113 | if (htmlContentAllowed) {
114 | button.setHTML(getState().delete);
115 | } else {
116 | button.setText(getState().delete);
117 | }
118 | button.setEnabled(enable);
119 | }
120 | }
121 |
122 | @Override
123 | public DeleteButtonClientRenderer getRenderer() {
124 | return (DeleteButtonClientRenderer) super.getRenderer();
125 | }
126 |
127 | @Override
128 | protected Renderer createRenderer() {
129 | return new DeleteButtonClientRenderer();
130 | }
131 |
132 | @Override
133 | protected HandlerRegistration addClickHandler(
134 | RendererClickHandler handler) {
135 | return getRenderer().addClickHandler(handler);
136 | }
137 |
138 | @Override
139 | public DeleteButtonRendererState getState() {
140 | return (DeleteButtonRendererState) super.getState();
141 | }
142 |
143 | @Override
144 | public void onStateChanged(StateChangeEvent stateChangeEvent) {
145 | super.onStateChanged(stateChangeEvent);
146 | getRenderer().setHtmlContentAllowed(getState().htmlContentAllowed);
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/DeleteButtonRenderer.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | import org.vaadin.patrik.shared.DeleteButtonRendererServerRpc;
6 | import org.vaadin.patrik.shared.DeleteButtonRendererState;
7 |
8 | import com.vaadin.event.ConnectorEventListener;
9 | import com.vaadin.event.MouseEvents.ClickEvent;
10 | import com.vaadin.shared.MouseEventDetails;
11 | import com.vaadin.shared.Registration;
12 | import com.vaadin.ui.Grid;
13 | import com.vaadin.ui.Grid.Column;
14 | import com.vaadin.ui.renderers.ButtonRenderer;
15 | import com.vaadin.ui.renderers.ClickableRenderer;
16 | import com.vaadin.ui.renderers.ClickableRenderer.RendererClickEvent;
17 | import com.vaadin.util.ReflectTools;
18 |
19 | /**
20 | * This is not maintained anymore. DeleteButtonRenderer has moved to Grid RenderersCollection add-on
21 | *
22 | * @deprecated since 2.1.4
23 | *
24 | * @param Type of the bean
25 | *
26 | * @author Tatu Lund
27 | */
28 | @Deprecated
29 | public class DeleteButtonRenderer extends ClickableRenderer {
30 |
31 | /**
32 | * An interface for listening to {@link DeleteRendererClickEvent renderer click
33 | * events}.
34 | *
35 | */
36 | @FunctionalInterface
37 | public interface DeleteRendererClickListener extends ConnectorEventListener {
38 |
39 | static final Method CLICK_METHOD = ReflectTools.findMethod(
40 | DeleteRendererClickListener.class, "click", DeleteRendererClickEvent.class);
41 |
42 | /**
43 | * Called when a rendered button is clicked.
44 | *
45 | * @param event
46 | * the event representing the click
47 | */
48 | void click(DeleteRendererClickEvent event);
49 | }
50 |
51 | /**
52 | * An event fired when a clickable widget rendered by a DeleteButtonRenderer is
53 | * clicked.
54 | *
55 | * @param
56 | * the item type associated with this click event
57 | */
58 | public static class DeleteRendererClickEvent extends ClickEvent {
59 |
60 | private final T item;
61 | private final Column column;
62 |
63 | protected DeleteRendererClickEvent(Grid source, T item,
64 | Column column, MouseEventDetails mouseEventDetails) {
65 | super(source, mouseEventDetails);
66 | this.item = item;
67 | this.column = column;
68 | }
69 |
70 | /**
71 | * Returns the item of the row where the click event originated.
72 | *
73 | * @return the item of the clicked row
74 | */
75 | public T getItem() {
76 | return item;
77 | }
78 |
79 | /**
80 | * Returns the {@link Column} where the click event originated.
81 | *
82 | * @return the column of the click event
83 | */
84 | public Column getColumn() {
85 | return column;
86 | }
87 | }
88 |
89 |
90 | /**
91 | * Creates a new button renderer
92 | * and e.g. localized Strings for meaning delete and confirm
93 | *
94 | * @param delete
95 | * text meaning delete
96 | * @param confirm
97 | * text meaning confirm
98 | */
99 | public DeleteButtonRenderer(String delete, String confirm) {
100 | super(Boolean.class, "");
101 | getState().delete = delete;
102 | getState().confirm = confirm;
103 | setupRpc();
104 | }
105 |
106 | /**
107 | * Creates a new delete button renderer and adds the given click listener to it
108 | * and e.g. localized Strings for meaning delete and confirm
109 | *
110 | * @param listener
111 | * the click listener to register
112 | * @param delete
113 | * text meaning delete
114 | * @param confirm
115 | * text meaning confirm
116 | */
117 | public DeleteButtonRenderer(DeleteRendererClickListener listener,
118 | String delete, String confirm) {
119 | this(delete, confirm);
120 | addClickListener(listener);
121 | }
122 |
123 | /**
124 | * Creates a new delete button renderer.
125 | *
126 | * Delete button renderer creates two stage Delete - Confirm button
127 | * When in confirm state "delete-confirm" stylename is set.
128 | */
129 | public DeleteButtonRenderer() {
130 | this("Delete","Confirm");
131 | }
132 |
133 | /**
134 | * Creates a new button renderer and adds the given click listener to it.
135 | *
136 | * @param listener
137 | * the click listener to register
138 | */
139 | public DeleteButtonRenderer(DeleteRendererClickListener listener) {
140 | this(listener, "Delete", "Confirm");
141 | }
142 |
143 | private void setupRpc() {
144 | registerRpc(new DeleteButtonRendererServerRpc() {
145 | public void onClick(String rowKey, MouseEventDetails mouseEventDetails) {
146 | Grid grid = getParentGrid();
147 | Object item = grid.getDataCommunicator().getKeyMapper().get(rowKey);
148 | Column column = getParent();
149 | fireEvent(new DeleteRendererClickEvent(grid,item,column,mouseEventDetails));
150 | }
151 | });
152 | }
153 |
154 | @Override
155 | public String getNullRepresentation() {
156 | return super.getNullRepresentation();
157 | }
158 |
159 | @Override
160 | protected DeleteButtonRendererState getState() {
161 | return (DeleteButtonRendererState) super.getState();
162 | }
163 |
164 | @Override
165 | protected DeleteButtonRendererState getState(boolean markAsDirty) {
166 | return (DeleteButtonRendererState) super.getState(markAsDirty);
167 | }
168 |
169 | /**
170 | * Sets whether the data should be rendered as HTML (instead of text).
171 | *
172 | * By default everything is rendered as text.
173 | *
174 | * @param htmlContentAllowed
175 | * true to render as HTML, false to
176 | * render as text
177 | */
178 | public void setHtmlContentAllowed(boolean htmlContentAllowed) {
179 | getState().htmlContentAllowed = htmlContentAllowed;
180 | }
181 |
182 | /**
183 | * Gets whether the data should be rendered as HTML (instead of text).
184 | *
185 | * By default everything is rendered as text.
186 | *
187 | * @return true if the renderer renders a HTML,
188 | * false if the content is rendered as text
189 | */
190 | public boolean isHtmlContentAllowed() {
191 | return getState(false).htmlContentAllowed;
192 | }
193 |
194 | public Registration addClickListener(DeleteRendererClickListener listener) {
195 | return addListener(DeleteRendererClickEvent.class, listener,
196 | DeleteRendererClickListener.CLICK_METHOD);
197 | }
198 |
199 |
200 | }
201 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/DemoUI.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | import javax.servlet.annotation.WebServlet;
4 |
5 | import com.vaadin.annotations.PreserveOnRefresh;
6 | import com.vaadin.annotations.Push;
7 | import com.vaadin.annotations.Theme;
8 | import com.vaadin.annotations.Title;
9 | import com.vaadin.annotations.VaadinServletConfiguration;
10 | import com.vaadin.icons.VaadinIcons;
11 | import com.vaadin.server.VaadinRequest;
12 | import com.vaadin.server.VaadinServlet;
13 | import com.vaadin.shared.communication.PushMode;
14 | import com.vaadin.shared.ui.ui.Transport;
15 | import com.vaadin.ui.Button;
16 | import com.vaadin.ui.Grid.SelectionMode;
17 | import com.vaadin.ui.HorizontalLayout;
18 | import com.vaadin.ui.UI;
19 | import com.vaadin.ui.VerticalLayout;
20 | import com.vaadin.ui.themes.ValoTheme;
21 |
22 | //@Push
23 | //@PreserveOnRefresh
24 | @Theme("demo")
25 | @Title("GridFastNavigation Add-on Demo")
26 | @SuppressWarnings("serial")
27 | public class DemoUI extends UI {
28 |
29 | @WebServlet(value = "/*", asyncSupported = true)
30 | @VaadinServletConfiguration(productionMode = false, ui = DemoUI.class, heartbeatInterval=5, closeIdleSessions=true, widgetset = "org.vaadin.patrik.demo.DemoWidgetSet")
31 | public static class Servlet extends VaadinServlet {
32 | }
33 |
34 | @Override
35 | protected void init(VaadinRequest vaadinRequest) {
36 | // getPushConfiguration().setPushMode(PushMode.DISABLED);
37 | final VerticalLayout layout = new VerticalLayout();
38 | layout.setSizeFull();
39 |
40 | MessageGrid messageGrid = new MessageGrid();
41 | DemoFastGrid demoGrid = new DemoFastGrid(messageGrid);
42 |
43 | Button clearButton = new Button("Clear");
44 | clearButton.addClickListener(e -> {
45 | messageGrid.clear();
46 | });
47 |
48 | Button addButton = new Button();
49 | addButton.setIcon(VaadinIcons.PLUS_CIRCLE); // Add Row
50 | addButton.addClickListener(e -> {
51 | demoGrid.addBlankRow();
52 | });
53 | addButton.setDescription("Add a new row");
54 |
55 | Button rowValidationButton = new Button();
56 | rowValidationButton.setIcon(VaadinIcons.CHECK_CIRCLE_O);
57 | rowValidationButton.setStyleName(ValoTheme.BUTTON_QUIET);
58 | rowValidationButton.addClickListener(e -> {
59 | demoGrid.getNavigation().setRowValidation(!demoGrid.getNavigation().getRowValidation());
60 | if (!demoGrid.getNavigation().getRowValidation()) rowValidationButton.setStyleName(ValoTheme.BUTTON_QUIET);
61 | else rowValidationButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
62 | });
63 | rowValidationButton.setDescription("Toggle rowValidation");
64 |
65 | Button rowOpenClickButton = new Button();
66 | rowOpenClickButton.setIcon(VaadinIcons.FOLDER_OPEN_O);
67 | rowOpenClickButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
68 | rowOpenClickButton.addClickListener(e -> {
69 | demoGrid.getNavigation().setOpenEditorWithSingleClick(!demoGrid.getNavigation().getOpenEditorWithSingleClick());
70 | if (!demoGrid.getNavigation().getOpenEditorWithSingleClick()) rowOpenClickButton.setStyleName(ValoTheme.BUTTON_QUIET);
71 | else rowOpenClickButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
72 | });
73 | rowOpenClickButton.setDescription("Toggle openEditorWithSingleClick");
74 |
75 | Button rowOpenByTypingButton = new Button();
76 | rowOpenByTypingButton.setIcon(VaadinIcons.KEYBOARD_O);
77 | rowOpenByTypingButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
78 | rowOpenByTypingButton.addClickListener(e -> {
79 | demoGrid.getNavigation().setOpenEditorOnTyping(!demoGrid.getNavigation().getOpenEditorOnTyping());
80 | if (!demoGrid.getNavigation().getOpenEditorOnTyping()) rowOpenByTypingButton.setStyleName(ValoTheme.BUTTON_QUIET);
81 | else rowOpenByTypingButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
82 | });
83 | rowOpenByTypingButton.setDescription("Toggle openEditorOnTyping");
84 |
85 | Button openEditorButton = new Button();
86 | openEditorButton.setIcon(VaadinIcons.INPUT);
87 | openEditorButton.setDescription("Open editor at 1,3");
88 | openEditorButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
89 | openEditorButton.addClickListener(e->{
90 | demoGrid.openEditor();
91 | });
92 |
93 | Button disableGridEditButton = new Button();
94 | disableGridEditButton.setIcon(VaadinIcons.PENCIL);
95 | disableGridEditButton.setDescription("Toggle Grid Editing");
96 | disableGridEditButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
97 | disableGridEditButton.addClickListener(e->{
98 | if (demoGrid.getEditor().isEnabled()) {
99 | if (demoGrid.getEditor().isOpen()) {
100 | demoGrid.getEditor().cancel();
101 | }
102 | demoGrid.getEditor().setEnabled(false);
103 | openEditorButton.setEnabled(false);
104 | disableGridEditButton.setStyleName(ValoTheme.BUTTON_QUIET);
105 | } else {
106 | demoGrid.getEditor().setEnabled(true);
107 | openEditorButton.setEnabled(true);
108 | disableGridEditButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
109 | }
110 | });
111 |
112 | Button moveSelectionButton = new Button();
113 | moveSelectionButton.setIcon(VaadinIcons.BULLSEYE);
114 | moveSelectionButton.setDescription("Toggle select follow");
115 | moveSelectionButton.setStyleName(ValoTheme.BUTTON_QUIET);
116 | moveSelectionButton.addClickListener(e->{
117 | if (demoGrid.moveSelection) {
118 | demoGrid.moveSelection = false;
119 | demoGrid.deselectAll();
120 | demoGrid.setSelectionMode(SelectionMode.NONE);
121 | moveSelectionButton.setStyleName(ValoTheme.BUTTON_QUIET);
122 | } else {
123 | demoGrid.moveSelection = true;
124 | demoGrid.setSelectionMode(SelectionMode.SINGLE);
125 | moveSelectionButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
126 | }
127 | });
128 |
129 | Button resetFocusButton = new Button();
130 | resetFocusButton.setIcon(VaadinIcons.CORNER_UPPER_LEFT);
131 | resetFocusButton.setDescription("Reset focust to 0,1");
132 | resetFocusButton.setStyleName(ValoTheme.BUTTON_FRIENDLY);
133 | resetFocusButton.addClickListener(e->{
134 | demoGrid.resetFocus();
135 | });
136 |
137 | Button pushButton = new Button("Push");
138 | pushButton.setDisableOnClick(true);
139 | pushButton.addClickListener(e -> {
140 | getPushConfiguration().setPushMode(PushMode.AUTOMATIC);
141 | getPushConfiguration().setTransport(Transport.LONG_POLLING);
142 | });
143 |
144 | HorizontalLayout buttons = new HorizontalLayout();
145 | buttons.addComponents(addButton,rowValidationButton,rowOpenClickButton,rowOpenByTypingButton,disableGridEditButton,moveSelectionButton,resetFocusButton,openEditorButton,pushButton);
146 |
147 | layout.setMargin(true);
148 | layout.setSpacing(true);
149 | layout.addComponent(demoGrid);
150 | layout.addComponent(buttons);
151 | layout.addComponent(messageGrid);
152 | layout.addComponent(clearButton);
153 | layout.setSizeFull();
154 | layout.setExpandRatio(demoGrid, 10);
155 | layout.setExpandRatio(buttons, 1);
156 | layout.setExpandRatio(clearButton, 1);
157 | layout.setExpandRatio(messageGrid, 6);
158 |
159 | setContent(layout);
160 | }
161 | }
--------------------------------------------------------------------------------
/GridFastNavigation-addon/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.vaadin.patrik
6 | GridFastNavigation
7 | jar
8 | 2.6.4
9 | GridFastNavigation Add-on
10 |
11 |
12 | UTF-8
13 | 1.8
14 | 1.8
15 | 8.14.3
16 | ${vaadin.version}
17 |
18 |
19 | ${project.version}
20 |
21 | ${project.name}
22 | ${project.organization.name}
23 | Apache License 2.0
24 | ${project.artifactId}-${project.version}.jar
25 |
26 |
27 |
28 | Tatu Lund
29 | https://github.com/tatulund/GridFastNavigation/
30 |
31 |
32 |
33 | git://github.com/tatulund/GridFastNavigation.git
34 | scm:git:git://github.com/tatulund/GridFastNavigation.git
35 | scm:git:ssh://git@github.com:/tatulund/${ComponentClassName}.git
36 | GridFastNavigation add-on for Vaadin
37 |
38 |
39 |
40 | GitHub
41 | https://github.com/tatulund/GridFastNavigation/issues
42 |
43 |
44 |
45 |
46 | Apache 2
47 | https://www.apache.org/licenses/LICENSE-2.0.txt
48 | repo
49 |
50 |
51 |
52 |
53 |
54 | vaadin-addons
55 | https://maven.vaadin.com/vaadin-addons
56 |
57 |
58 | vaadin-snapshots
59 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/
60 |
61 | false
62 |
63 |
64 | true
65 |
66 |
67 |
68 |
69 |
70 |
71 | vaadin-snapshots
72 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/
73 |
74 | false
75 |
76 |
77 | true
78 |
79 |
80 |
81 |
82 |
83 |
84 | com.vaadin
85 | vaadin-server
86 | ${vaadin.version}
87 |
88 |
89 | com.vaadin
90 | vaadin-client
91 | ${vaadin.version}
92 | provided
93 |
94 |
95 | junit
96 | junit
97 | 4.13.1
98 | test
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | org.apache.maven.plugins
107 | maven-compiler-plugin
108 | 3.0
109 |
110 |
111 |
112 | org.apache.maven.plugins
113 | maven-jar-plugin
114 | 2.3.1
115 |
116 |
117 | true
118 |
119 | true
120 | true
121 |
122 |
123 |
124 | 1
125 | ${Vaadin-License-Title}
126 | org.vaadin.patrik.GridFastNavigationWidgetSet
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | org.apache.maven.plugins
148 | maven-source-plugin
149 | 2.2.1
150 |
151 |
152 | attach-sources
153 |
154 | jar
155 |
156 |
157 |
158 |
159 |
160 |
161 | org.apache.maven.plugins
162 | maven-assembly-plugin
163 | 2.2.1
164 |
165 | false
166 |
167 | assembly/assembly.xml
168 |
169 |
170 |
171 |
172 |
173 | single
174 |
175 | install
176 |
177 |
178 |
179 |
180 |
181 |
182 | org.apache.maven.plugins
183 | maven-surefire-plugin
184 | 2.14.1
185 |
186 |
187 |
188 |
190 |
191 |
192 | src/main/java
193 |
194 | rebel.xml
195 |
196 |
197 |
198 | src/main/resources
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 | vaadin-prerelease
208 |
209 | false
210 |
211 |
212 |
213 |
214 | vaadin-prereleases
215 | https://maven.vaadin.com/vaadin-prereleases
216 |
217 |
218 |
219 |
220 | vaadin-prereleases
221 | https://maven.vaadin.com/vaadin-prereleases
222 |
223 |
224 |
225 |
226 |
227 |
228 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.vaadin.patrik
6 | GridFastNavigation-demo
7 | war
8 | 2.6.4
9 | GridFastNavigation Add-on Demo
10 |
11 |
12 | UTF-8
13 | 1.8
14 | 1.8
15 | 8.14.3
16 | ${vaadin.version}
17 |
18 | 9.4.36.v20210114
19 |
20 |
21 |
22 | Tatu Lund
23 | https://github.com/tatulund/GridFastNavigation/
24 |
25 |
26 |
27 | git://github.com/tatulund/GridFastNavigation.git
28 | scm:git:git://github.com/tatulund/GridFastNavigation.git
29 | scm:git:ssh://git@github.com:/tatulund/${ComponentClassName}.git
30 | GridFastNavigation add-on for Vaadin
31 |
32 |
33 |
34 | GitHub
35 | https://github.com/tatulund/GridFastNavigation/issues
36 |
37 |
38 |
39 |
40 | Apache 2
41 | https://www.apache.org/licenses/LICENSE-2.0.txt
42 | repo
43 |
44 |
45 |
46 |
47 |
48 | vaadin-addons
49 | https://maven.vaadin.com/vaadin-addons
50 |
51 |
52 | vaadin-snapshots
53 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/
54 |
55 | false
56 |
57 |
58 | true
59 |
60 |
61 |
62 |
63 |
64 |
65 | vaadin-snapshots
66 | https://oss.sonatype.org/content/repositories/vaadin-snapshots/
67 |
68 | false
69 |
70 |
71 | true
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | com.vaadin
80 | vaadin-bom
81 | ${vaadin.version}
82 | pom
83 | import
84 |
85 |
86 |
87 |
88 |
89 |
90 | org.vaadin.patrik
91 | GridFastNavigation
92 | ${project.version}
93 |
94 |
95 | com.vaadin
96 | grid-renderers-collection-addon
97 | 2.2.10
98 |
99 |
100 | org.vaadin.ui
101 | numberfield
102 | 0.2.0
103 |
104 |
105 | org.vaadin
106 | prefixcombobox
107 | 1.4.0
108 |
109 |
110 | com.vaadin
111 | vaadin-push
112 |
113 |
114 | com.vaadin
115 | vaadin-push
116 |
117 |
118 | com.vaadin
119 | vaadin-client-compiler
120 | provided
121 |
122 |
123 | com.vaadin
124 | vaadin-themes
125 |
126 |
127 | javax.servlet
128 | javax.servlet-api
129 | 3.0.1
130 | provided
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | org.apache.maven.plugins
140 | maven-compiler-plugin
141 | 3.0
142 |
143 |
144 |
145 | maven-clean-plugin
146 | 2.4.1
147 |
148 |
149 |
150 |
151 | ${basedir}/src/main/webapp/VAADIN/widgetsets
152 |
153 |
154 |
155 | ${basedir}/src/main/webapp/VAADIN/gwt-unitCache
156 |
157 |
158 |
159 |
160 |
161 |
162 | maven-war-plugin
163 | 2.3
164 |
165 |
166 | **/VAADIN/gwt-unitCache/**,
167 | **/VAADIN/widgetsets/WEB-INF/**,
168 | **/WEB-INF/classes/gwt-unitCache/**,
169 | **/WEB-INF/classes/themes/**,
170 | **/WEB-INF/classes/widgetsets/**
171 |
172 | false
173 |
174 |
175 |
176 |
177 | com.vaadin
178 | vaadin-maven-plugin
179 | ${vaadin.plugin.version}
180 |
181 | -Xmx512M -Xss1024k
182 | ${basedir}/src/main/webapp/VAADIN/widgetsets
183 | ${basedir}/src/main/webapp/VAADIN/widgetsets
184 | true
185 | ${basedir}/target/tmp/gwt-unitCache
186 | false
187 | true
188 | http://localhost:8080/
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 | update-theme
199 | resources
200 | update-widgetset
201 | compile
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 | org.eclipse.jetty
211 | jetty-maven-plugin
212 | ${jetty.plugin.version}
213 |
214 | 2
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 | org.eclipse.m2e
225 | lifecycle-mapping
226 | 1.0.0
227 |
228 |
229 |
230 |
231 |
232 | com.vaadin
233 | vaadin-maven-plugin
234 |
235 | [${vaadin.plugin.version},)
236 |
237 |
238 | resources
239 | update-widgetset
240 | compile
241 | update-theme
242 | compile-theme
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 | vaadin-prerelease
263 |
264 | false
265 |
266 |
267 |
268 |
269 | vaadin-prereleases
270 | http://maven.vaadin.com/vaadin-prereleases
271 |
272 |
273 |
274 |
275 | vaadin-prereleases
276 | http://maven.vaadin.com/vaadin-prereleases
277 |
278 |
279 |
280 |
281 |
282 |
283 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://vaadin.com/directory/component/gridfastnavigation-add-on)
2 | [](https://vaadin.com/directory/component/gridfastnavigation-add-on)
3 |
4 | # GridFastNavigation Add-on for Vaadin 8
5 |
6 | Do you like the Grid but would want it to appeal more to old Excel jockeys?
7 | Then this add-on is for you!
8 | GridFastNavigation is a compnent extension for Vaadin Grid, which uses the
9 | unbuffered editing mode and alters its keyboard controls to provide a faster
10 | editing experience.
11 |
12 | ## Online demo
13 | [Todo](...)
14 |
15 | ## Download release
16 |
17 | Official releases of this add-on are available at Vaadin Directory. For Maven instructions, download and reviews, go to
18 | https://vaadin.com/directory/component/gridfastnavigation-add-on
19 |
20 | ## JavaDoc
21 |
22 | JavaDoc can be found online at
23 |
24 | https://vaadin.com/directory/component/gridfastnavigation-add-on/api
25 |
26 | ## Building and running demo
27 |
28 | git clone https://github.com/thinwire/GridFastNavigation.git
29 | mvn clean install
30 | cd GridFastNavigation-demo
31 | mvn jetty:run
32 |
33 | To see the demo, navigate to http://localhost:8080/
34 |
35 | ## Development with Eclipse IDE
36 |
37 | For further development of this add-on, the following tool-chain is recommended:
38 | - Eclipse IDE
39 | - m2e wtp plug-in (install it from Eclipse Marketplace)
40 | - Vaadin Eclipse plug-in (install it from Eclipse Marketplace)
41 | - Chrome browser
42 |
43 | ### Importing project
44 |
45 | Choose File > Import... > Existing Maven Projects
46 |
47 | Note that Eclipse may give "Plugin execution not covered by lifecycle configuration" errors for pom.xml. Use "Permanently mark goal resources in pom.xml as ignored in Eclipse build" quick-fix to mark these errors as permanently ignored in your project. Do not worry, the project still works fine.
48 |
49 | ### Debugging server-side
50 |
51 | If you have not already compiled the widgetset, do it now by running vaadin:install Maven target for GridFastNavigation-root project.
52 |
53 | If you have a JRebel license, it makes on the fly code changes faster. Just add JRebel nature to your GridFastNavigation-demo project by clicking project with right mouse button and choosing JRebel > Add JRebel Nature
54 |
55 | To debug project and make code modifications on the fly in the server-side, right-click the GridFastNavigation-demo project and choose Debug As > Debug on Server. Navigate to http://localhost:8080/ to see the application.
56 |
57 | ### Debugging client-side
58 |
59 | Debugging client side code in the GridFastNavigation-demo project:
60 | - run "mvn vaadin:run-codeserver" on a separate console while the application is running
61 | - activate Super Dev Mode in the debug window of the application or by adding ?superdevmode to the URL
62 | - You can access Java-sources and set breakpoints inside Chrome if you enable source maps from inspector settings.
63 |
64 | ## Release notes
65 |
66 | ### Version 2.6.4
67 | - Adjust timing of the focus and selectAll calls.
68 |
69 | ### Version 2.6.3
70 | - Fix editor column resizing in multiselect mode
71 |
72 | ### Version 2.6.1
73 | - Fixed possible issue when there is empty data set in grid
74 |
75 | ### Version 2.6.0
76 | - Do not change row if Alt Shift or Ctrl pressed (see issue #102)
77 | - Added getKeyCode to EditorOpenEvent (see issue #101)
78 | - Added isUserOriginated to CellFocusEvent and EditorOpenEvent (see issue #99)
79 |
80 | ### Version 2.5.6
81 | - Fixed column sizing issues in when using Frozen columns.
82 |
83 | ### Version 2.5.5
84 | - Fixed NPE in when using Frozen columns.
85 |
86 | ### Version 2.5.4
87 | - Fixed timing issue if editRow(row,col) was called during Grid is updating after dataProvider.refreshAll()
88 |
89 | ### Version 2.5.3
90 | - Added some error handling
91 |
92 | ### Version 2.5.2
93 | - Added method to open Editor at row X in column Y
94 | - Fix: Disabled column styles were not applied dynamically
95 |
96 | ### Version 2.5.1
97 | - Grid froze when last column was not editable, fixes issue #98
98 |
99 | ### Version 2.5.0
100 | - Fixed typo in method name, fixes issue #97
101 | - Fixed hidden column compensation logic, fixes issue #96
102 | - Codebase maintenance
103 |
104 | ### Version 2.4.8
105 | - Add-on also now supports custom editor widgets extending the base set of editors
106 |
107 | ### Version 2.4.7
108 | - Fixed editor cell resizing logic to work also with multiselect mode.
109 |
110 | ### Version 2.4.6
111 | - Added option to enable selected style in Editor on selected row
112 | - Fixed bug in cell focus event not triggered when moving left in multiselect Grid, fixes issue #95
113 |
114 | ### Version 2.4.5
115 | - Fixed missing implementation of CellEditEvent#getOldData(), see issue #91
116 |
117 | ### Version 2.4.4
118 | - Fixed CellFocusEvent#wasRowChanged() and CellFocusEvent#wasColumnChanged() to work correctly
119 |
120 | ### Version 2.4.3
121 | - Added feature: shift+space will select / deselect the row when editor is open, see issue #90
122 |
123 | ### Version 2.4.2
124 | - Fixed bug: In edit events item and row index were not correct or in sync in certain corner cases
125 |
126 | ### Version 2.4.1
127 | - Made OffsetHelper serializable, to address issue #86
128 | - Fixed JavaDocs
129 |
130 | ### Version 2.4.0
131 | - Added support for NativeSelect, ColorPicker and TextArea
132 | - Improved setFocusedCell(..) to address issue #77
133 |
134 | ### Version 2.3.10
135 | - Improvement: issue #82 add helper to deal with custom selection models that change internal column calculation
136 | - Added fault checkign to setFocusedCel due issue #77 and setChangeColumnOnEnter methods
137 | - Improved JavaDocs
138 |
139 | ### Version 2.3.9
140 | - Fix: Grid scroll bar width was not taken into account in Editor resizing
141 |
142 | ### Version 2.3.8
143 | - Further improvement to row validation mode
144 |
145 | ### Version 2.3.7
146 | - Improvement to row validation mode
147 |
148 | ### Version 2.3.6
149 | - Added fix to Editor not resized when browser window is being resized bug. See: https://github.com/vaadin/framework/issues/11148
150 |
151 | ### Version 2.3.5
152 | - Workaround for https://github.com/vaadin/framework/issues/8962
153 | - Workaround for https://github.com/vaadin/framework/issues/7276
154 |
155 | ### Version 2.3.4
156 | - Fixed bug: Problem with sorting, edit event did not return right item (issue #76).
157 | - Improvement: Home/End key behavior can be disabled with setHomeEndEnabled(false) (issue #75)
158 | - New feature: Move focus programmatically with setFocusedCel(row,col) (issue #68)
159 | - Updated demo
160 |
161 | ### Version 2.3.3
162 | - Fixed bug: Client side exception occurred when there were hidden columns (issue #74).
163 |
164 | ### Version 2.3.2
165 | - Added convenience method disableAllColumns() in EditorOpenEvent (issue #27)
166 | - Fixed bug: Editor opening was jammed if there were no editable columns
167 |
168 | ### Version 2.3.1
169 | - Fixed bug: Tabing out of bounds caused client side exception.
170 |
171 | ### Version 2.3.0
172 | - Added preliminary support for hidden columns, fixes issue #71
173 | - Minor improvements in setRowValidation(true) mode
174 | - Updated demo
175 |
176 | ### Version 2.2.4
177 | - Fix bug: Clicking outside Grid when setRowValidation(true) closed editor
178 |
179 | ### Version 2.2.3
180 | - Improvements to full row validation (see issues #69 and #51), with setRowValidation(..) API
181 |
182 | ### Version 2.2.2
183 | - Making possible to have full row validation (see issues #69 and #51)
184 | - Updated demo
185 |
186 | ### Version 2.2.1
187 | - Fixing issue #67: ESC-Click combination froze editor
188 |
189 | ### Version 2.2.0
190 | - Fixed issue #65: Column indeces where off by one with multiselect model, and column disabling did not work
191 | - Changed behavior, FastNavigation will no longer force Editor to be enabled
192 |
193 | ### Version 2.1.20
194 | - Fixed issue #64: RowEditEvent fired after ESC-key
195 |
196 | ### Version 2.1.19
197 | - Fixed issue #63: Numpad input was not filttered properly
198 |
199 | ### Version 2.1.18
200 | - Fixed serialization issue
201 | - Made EditorWidgets.registerHandler(..) public so that it is possible to add your custom editor widget handlers, and added java docs.
202 | - Fix: Selection of the ComboBox textfield was missing
203 |
204 | ### Version 2.1.17
205 | - Fix: Do not fire ClickOutEvent if ComboBox or DateField is open.
206 |
207 | ### Version 2.1.16
208 | - Returned disableColumns(..) to EditorOpenEvent. It can be used to disable additional columns from editing.
209 |
210 | ### Version 2.1.15
211 | - Fix, clickOutListener did not work if FastNavigation was not instantiated with dispatchEditEventOnBlur=true parameter (issue: #54)
212 |
213 | ### Version 2.1.14
214 | - Fix, disabled columns / readonly fields detection logic was flawed (see: issue #55)
215 | - Fixing internal columns handling (see: issue #50)
216 | - Fix, Internal method to get item for events, did NPE with empty DataProvider (see: issue #56)
217 |
218 | ### Version 2.1.13
219 | - Bugfix, cursor up/down did not open ComboBox in IE11
220 |
221 | ### Version 2.1.12
222 | - Fixing issue #52
223 |
224 | ### Version 2.1.11
225 | - Added possibility to add save shortcuts (see: issue #49)
226 | - setSaveWithCtrlS(true) -> CTRL+S does save and close editor
227 |
228 | ### Version 2.1.10
229 | - Solving issue #42: Clarifying setOpenEditorWithSingleClick(true) JavaDoc. Using it will prevent Grid's item click event and selection event getting the click.
230 |
231 | ### Version 2.1.9
232 | - Changed getItem() in selected events to use DataCommunicator, requires Vaadin 8.2+
233 |
234 | ### Version 2.1.8
235 | - Added ClickOutListener
236 |
237 | ### Version 2.1.7
238 | - Changed widgetset.xml filename, Fixed issues #40, #41
239 |
240 | ### Version 2.1.6
241 | - Modified CellFocusEvent and RowFocusEvent to return -1 if focus is in Header/Footer
242 | - Updated JavaDocs
243 |
244 | ### Version 2.1.5
245 | - Added getItem() to RowFocusEvent and CellFocusEvent
246 | - Minor bugfix, there was regression in fix for issue #35
247 |
248 | ### Version 2.1.4
249 | - Added getItem() CellEditEvent and RowEditEvent (experimental)
250 | - Fixed issue #37: Enter now saves the value when closing the editor in the last cell
251 | - Fixed issue #35: Listeners should be able to be used automatically now.
252 | - DeleteButtonRenderer deprecated, it is now maintained in Grid RenderersCollection add-on.
253 | - Updated the demo.
254 |
255 | ### Version 2.1.3
256 | - Added support for closing Editor and dispatching event when clicking outside of Grid.
257 |
258 | ### Version 2.1.2
259 | - DeleteButtonRenderer, made it boolean type, so that property underneath controls whether the button is enabled or not
260 |
261 | ### Version 2.1.1
262 | - Fixed DeleteButtonRenderer: Html content mode support in client side was missing
263 | - Demo updated
264 |
265 | ### Version 2.1.0
266 | - Added DeleteButtonRenderer
267 | - Demo updated
268 |
269 | ### Version 2.0.0
270 | - First version for Vaadin 8
271 | - Features on par with version 0.5.7
272 | - Demo updated
273 |
274 | ## Issue tracking
275 |
276 | The issues for this add-on are tracked on its github.com page. All bug reports and feature requests are appreciated.
277 |
278 | ## Contributions
279 |
280 | Contributions are welcome, but there are no guarantees that they are accepted as such. Process for contributing is the following:
281 | - Fork this project
282 | - Create an issue to this project about the contribution (bug or feature) if there is no such issue about it already. Try to keep the scope minimal.
283 | - Develop and test the fix or functionality carefully. Only include minimum amount of code needed to fix the issue.
284 | - Refer to the fixed issue in commit
285 | - Send a pull request for the original project
286 | - Comment on the original issue that you have implemented a fix for it
287 |
288 | ## License & Author
289 |
290 | Add-on is distributed under Apache License 2.0. For license terms, see LICENSE.txt.
291 |
292 | GridFastNavigation is written by Patrik Lindström, Tatu Lund and Johannes Tuikkala and maintained by the Tatu. Vaadin 8 migration initial work was contributed by Brett Sutton.
293 |
294 | Major pieces of development of this add-on has been sponsored by multiple Support and Prime customers of Vaadin. See vaadin.com/support and Development on Demand for more details.
295 |
296 |
297 |
--------------------------------------------------------------------------------
/GridFastNavigation-demo/src/main/java/org/vaadin/patrik/demo/DemoFastGrid.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.demo;
2 |
3 | import java.text.DateFormat;
4 | import java.text.SimpleDateFormat;
5 | import java.time.OffsetDateTime;
6 | import java.time.ZoneId;
7 | import java.time.ZoneOffset;
8 | import java.util.ArrayList;
9 | import java.util.Arrays;
10 | import java.util.Date;
11 | import java.util.List;
12 |
13 | import org.vaadin.grid.cellrenderers.action.DeleteButtonRenderer;
14 | import org.vaadin.patrik.FastNavigation;
15 | import org.vaadin.prefixcombobox.PrefixComboBox;
16 | import org.vaadin.ui.NumberField;
17 |
18 | import com.vaadin.data.Binder;
19 | import com.vaadin.data.Binder.Binding;
20 | import com.vaadin.data.converter.LocalDateTimeToDateConverter;
21 | import com.vaadin.data.converter.LocalDateToDateConverter;
22 | import com.vaadin.data.converter.StringToIntegerConverter;
23 | import com.vaadin.data.provider.ListDataProvider;
24 | import com.vaadin.data.validator.IntegerRangeValidator;
25 | import com.vaadin.event.ShortcutAction.KeyCode;
26 | import com.vaadin.icons.VaadinIcons;
27 | import com.vaadin.ui.Button;
28 | import com.vaadin.ui.CheckBox;
29 | import com.vaadin.ui.DateField;
30 | import com.vaadin.ui.DateTimeField;
31 | import com.vaadin.ui.Grid;
32 | import com.vaadin.ui.TextField;
33 | import com.vaadin.ui.UI;
34 | import com.vaadin.ui.renderers.DateRenderer;
35 | import com.vaadin.ui.themes.ValoTheme;
36 |
37 | public class DemoFastGrid extends Grid {
38 | private static final long serialVersionUID = 1L;
39 |
40 | final List demoList;
41 | final ListDataProvider demoData;
42 | private FastNavigation nav;
43 | public boolean moveSelection = false;
44 |
45 | private MessageLog messageLog;
46 | private int lastEditedRow = 0;
47 |
48 | DemoFastGrid(MessageLog messageLog) {
49 | super("Fast Navigation Grid");
50 | this.messageLog = messageLog;
51 | demoList = new ArrayList<>();
52 | demoData = new ListDataProvider<>(demoList);
53 |
54 | this.setDataProvider(demoData);
55 | this.getHeaderRow(0).setStyleName("my-background");
56 |
57 | initNavigation();
58 |
59 | this.getEditor().setEnabled(true);
60 | this.getEditor().setBuffered(false);
61 |
62 | bindColumnsToEditor();
63 |
64 | // nav.editRow(1, 3);
65 | }
66 |
67 | private void initNavigation() {
68 |
69 | nav = new FastNavigation<>(this, false, true);
70 | nav.setChangeColumnAfterLastRow(true);
71 | nav.setOpenEditorWithSingleClick(true);
72 |
73 | nav.addRowEditListener(event -> {
74 | getDataProvider().refreshAll();
75 | int rowIndex = event.getRowIndex();
76 | if (rowIndex >= 0) {
77 | printChangedRow(rowIndex,(DemoColumns) event.getItem());
78 | }
79 | if (event.getItem() != null && ((DemoColumns) event.getItem()).getCol9() == true) {
80 | this.getColumn("col6").getEditorBinding().getField().setReadOnly(true);
81 | } else {
82 | this.getColumn("col6").getEditorBinding().getField().setReadOnly(false);
83 | }
84 | });
85 | // If you want to update Grid item values programmatically in Grid and get the updated values
86 | // shown Editor needs to be closed and reopened
87 | // nav.addCellEditListener(event -> {
88 | // int row = event.getRowIndex();
89 | // if (event.getColumnIndex() == 5) {
90 | // this.getEditor().save();
91 | // this.getEditor().cancel();
92 | // DemoColumns item = (DemoColumns) event.getItem();
93 | // item.setCol6(item.getCol5()+item.getCol6());
94 | // this.getDataProvider().refreshItem(item);
95 | // this.getEditor().editRow(row);
96 | // }
97 | // });
98 | nav.addCellEditListener(event -> {
99 | messageLog.writeOutput("Changed '" + event.getOldData() + "' -> '" + event.getNewData()+ "'");
100 | });
101 | // Obsolete in Vaadin 8.9+
102 | // nav.enableEditorSelectedStyle(true);
103 |
104 | DeleteButtonRenderer deleteButton = new DeleteButtonRenderer(clickEvent -> {
105 | if (this.getEditor().isOpen())
106 | this.getEditor().cancel();
107 |
108 | demoList.remove(clickEvent.getItem());
109 | this.getDataProvider().refreshAll();
110 | },VaadinIcons.TRASH.getHtml()+" Delete",VaadinIcons.CHECK.getHtml()+" Confirm");
111 | deleteButton.setHtmlContentAllowed(true);
112 | this.addColumn(action -> true,deleteButton).setId("delete").setCaption("Action").setWidth(120).setHidable(true);
113 |
114 | // Open with F2
115 | nav.addEditorOpenShortcut(KeyCode.F2);
116 | messageLog.writeOutput("Editor can also be opened with F2");
117 |
118 | // Close with F3
119 | nav.addEditorCloseShortcut(KeyCode.F3);
120 | messageLog.writeOutput("Editor can also be closed with F3");
121 |
122 | nav.setSaveWithCtrlS(true);
123 |
124 | Grid grid = this;
125 |
126 | // Row focus change
127 | nav.addRowFocusListener(event -> {
128 | if (moveSelection) {
129 | if (event.getRow() >= 0) grid.select((DemoColumns) event.getItem());
130 | else grid.deselectAll();
131 | }
132 | messageLog.writeOutput("Focus moved to row " + event.getRow());
133 | });
134 | messageLog.writeOutput("Added row focus change listener");
135 |
136 | // Cell focus change
137 | nav.addCellFocusListener(event -> {
138 | int row = event.getRow();
139 | int col = event.getColumnIndex();
140 | boolean userOriginated = event.isUserOriginated();
141 | messageLog.writeOutput("Focus moved to cell [" + row + ", " + col + " ]" + " from UI: "+userOriginated);
142 | // if (event.wasRowChanged() && this.getEditor().isOpen()) {
143 | // this.getEditor().cancel();
144 | // messageLog.writeOutput("Row was changed");
145 | // nav.setFocusedCell(row, 1);
146 | // this.getEditor().editRow(row);
147 | // }
148 | });
149 | messageLog.writeOutput("Added cell focus change listener");
150 |
151 | // Listening to opening of editor
152 | nav.addEditorOpenListener(event -> {
153 | // Uncomment to demonstrate conditional row editing
154 | // if (((DemoColumns) event.getItem()).getCol9()) event.disableAllColumns();
155 | // Or
156 | // event.disableColumns(1);
157 | int row = event.getRow();
158 | boolean userOriginated = event.isUserOriginated();
159 | int keyCode = event.getKeyCode();
160 | lastEditedRow = row;
161 | messageLog.writeOutput("Editor opened on row " + row + " at column " + event.getColumnIndex()+ " keyCode: "+keyCode+" from UI: "+userOriginated);
162 | });
163 | messageLog.writeOutput("Added editor open listener");
164 |
165 | // Listening to closing of editor
166 | nav.addEditorCloseListener(event -> {
167 | messageLog.writeOutput("Editor closed on row " + event.getRow() + ", column " + event.getColumnIndex() + ", "
168 | + (event.wasCancelled() ? "user cancelled change" : "user saved change"));
169 | });
170 | messageLog.writeOutput("Added editor close listener");
171 |
172 | nav.addClickOutListener(event -> {
173 | messageLog.writeOutput("User clicked outside Grid: "+event.getSource().toString());
174 | });
175 | }
176 |
177 | /**
178 | * We bind each column to a field (shared by all rows) so that we can edit
179 | * each cell.
180 | */
181 | private void bindColumnsToEditor() {
182 | TextField col1 = new TextField();
183 | TextField col3 = new TextField();
184 | NumberField col4 = new NumberField();
185 | TextField col5 = new TextField();
186 | TextField col6 = new TextField();
187 | DateTimeField col7 = new DateTimeField();
188 | DateField col8 = new DateField();
189 | CheckBox col9 = new CheckBox();
190 | col9.setDescription("Selecting this will disable Col6");
191 | PrefixComboBox col10 = new PrefixComboBox<>();
192 | List items = new ArrayList<>(Arrays.asList("small", "medium", "large"));
193 | // col10.setNewItemProvider(value -> {
194 | // items.add(value);
195 | // return Optional.ofNullable(value);
196 | // });
197 | col10.setEmptySelectionCaption("unsized");
198 |
199 | col10.setDataProvider(new ListDataProvider(items));
200 |
201 | Binder binder = this.getEditor().getBinder();
202 |
203 | // Col1 simple string
204 | Binding col1Binding = binder.forField(col1).asRequired("Empty value not accepted").bind(DemoColumns::getCol1,
205 | DemoColumns::setCol1);
206 | this.addColumn(DemoColumns::getCol1).setCaption("Col1").setExpandRatio(1).setEditorBinding(col1Binding);
207 |
208 | // Col2 non-editable string
209 | this.addColumn(DemoColumns::getCol2).setCaption("No Edits").setId("noedit").setHidable(true).setWidth(150);
210 |
211 | // Col3 Integer
212 | Binding col3Binding = binder.forField(col3).withNullRepresentation("")
213 | .withConverter(new StringToIntegerConverter("Must enter a number")).withValidator(new IntegerRangeValidator("Input integer between 0 and 10",0,10))
214 | .bind(DemoColumns::getCol3, DemoColumns::setCol3);
215 | this.addColumn(DemoColumns::getCol3).setCaption("Integer").setHidable(true).setWidth(150).setEditorBinding(col3Binding);
216 |
217 | // Col4 Float
218 | Binding col4Binding = binder.forField(col4).withNullRepresentation("")
219 | .withConverter(col4.getConverter("Must enter a number"))
220 | // .withConverter(new StringToFloatConverter("Must enter a number"))
221 | .bind(DemoColumns::getCol4, DemoColumns::setCol4);
222 | this.addColumn(DemoColumns::getCol4).setCaption("Float").setHidable(true).setWidth(100).setEditorBinding(col4Binding);
223 |
224 | // Col 5 Integer
225 | Binding col5Binding = binder.forField(col5).withNullRepresentation("")
226 | .withConverter(new StringToIntegerConverter("Must enter a number")).withValidator(new IntegerRangeValidator("Input integer between 0 and 10",0,10))
227 | .bind(DemoColumns::getCol5, DemoColumns::setCol5);
228 | this.addColumn(DemoColumns::getCol5).setCaption("Integer (2)").setHidable(true).setWidth(100).setEditorBinding(col5Binding);
229 |
230 | // Col6 Integer(3)
231 | Binding col6Binding = binder.forField(col6).withNullRepresentation("")
232 | .withConverter(new StringToIntegerConverter("Must enter a number")).withValidator(new IntegerRangeValidator("Input integer between 0 and 10",0,10))
233 | .bind(DemoColumns::getCol6, DemoColumns::setCol6);
234 | this.addColumn(DemoColumns::getCol6).setId("col6").setCaption("Col6").setHidable(true).setWidth(100).setEditorBinding(col6Binding);
235 |
236 | // Col 7 DateTime
237 | // Need a zoneoffset for datetimefield
238 | OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault());
239 | ZoneOffset zoneOffset = odt.getOffset();
240 |
241 | SimpleDateFormat dateTimeFormat = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,
242 | DateFormat.SHORT, UI.getCurrent().getLocale());
243 | Binding col7Binding = binder.forField(col7)
244 | .withConverter(new LocalDateTimeToDateConverter(zoneOffset))
245 | .bind(DemoColumns::getCol7, DemoColumns::setCol7);
246 | this.addColumn(DemoColumns::getCol7).setCaption("Date Time").setWidth(180).setEditorBinding(col7Binding)
247 | .setRenderer(new DateRenderer(dateTimeFormat)).setHidable(true);
248 |
249 | // col 8 Date
250 | Binding col8Binding = binder.forField(col8).withConverter(new LocalDateToDateConverter())
251 | .bind(DemoColumns::getCol8, DemoColumns::setCol8);
252 |
253 | SimpleDateFormat dateFormat = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,
254 | UI.getCurrent().getLocale());
255 | this.addColumn(DemoColumns::getCol8).setCaption("Date").setWidth(120).setEditorBinding(col8Binding)
256 | .setRenderer(new DateRenderer(dateFormat)).setHidable(true);
257 |
258 | // Col 9 Boolean
259 | Binding col10Binding = binder.forField(col9).bind(DemoColumns::getCol9,
260 | DemoColumns::setCol9);
261 | this.addColumn(DemoColumns::getCol9).setCaption("Boolean").setHidable(true).setWidth(150).setEditorBinding(col10Binding);
262 |
263 | // Col 10 Combobox.
264 | Binding col11Binding = binder.forField(col10).bind(DemoColumns::getCol10,
265 | DemoColumns::setCol10);
266 | this.addColumn(DemoColumns::getCol10).setCaption("Combobox").setHidable(true).setWidth(150).setEditorBinding(col11Binding);
267 |
268 | this.addComponentColumn(item -> {
269 | Button button = new Button("", VaadinIcons.TRASH);
270 | button.addStyleName(ValoTheme.BUTTON_BORDERLESS);
271 | button.addStyleName(ValoTheme.BUTTON_ICON_ONLY);
272 | button.setWidth(48, Unit.PIXELS);
273 | button.addClickListener(clickEvent -> {
274 | messageLog.writeOutput("Component button click");
275 | demoList.remove(item);
276 | this.getDataProvider().refreshAll();
277 | });
278 | return button;
279 | }).setHandleWidgetEvents(false).setWidth(70);
280 |
281 | for (int i = 0; i < 5; ++i) {
282 | demoList.add(new DemoColumns());
283 | }
284 | demoData.refreshAll();
285 | this.addItemClickListener(event -> {
286 | System.out.println("Item click event happens: "+event.getItem().toString());
287 | });
288 | this.setSizeFull();
289 | // nav.setFocusedCell(2, 2, true);
290 | this.select(demoList.get(2));
291 | // this.setFrozenColumnCount(2);
292 |
293 | this.appendHeaderRow();
294 | for (Column col : this.getColumns()) {
295 | if (col.getId() == null || (col.getId() != null && !(col.getId().equals("noedit") || col.getId().equals("delete")))) {
296 | CheckBox editable = new CheckBox();
297 | editable.setValue(true);
298 | editable.addValueChangeListener(event -> {
299 | if (!getEditor().isOpen()) {
300 | if (event.getValue()) {
301 | col.setEditable(true);
302 | } else {
303 | col.setEditable(false);
304 | }
305 | } else if (event.isUserOriginated()) {
306 | editable.setValue(!editable.getValue());
307 | }
308 | });
309 | this.getHeaderRow(1).getCell(col).setComponent(editable);
310 | }
311 | }
312 | }
313 |
314 | // Add a blank row to the grid and tell the grid to refresh itself showing
315 | // the new row.
316 | public void addBlankRow() {
317 | // its an unbuffered editor so canceling doesn't lose data just closes
318 | // the
319 | // editor.
320 | if (getEditor().isOpen()) {
321 | this.getEditor().cancel();
322 | }
323 | demoList.add(new DemoColumns());
324 | this.recalculateColumnWidths();
325 | this.getDataProvider().refreshAll();
326 | int row = this.getDataCommunicator().getDataProviderSize()-1;
327 | nav.editRow(row,0);
328 | }
329 |
330 | public FastNavigation getNavigation() {
331 | return nav;
332 | }
333 |
334 | private void printChangedRow(int rowIndex, DemoColumns rowData) {
335 | if (demoList.size() >= rowIndex) {
336 | // DemoColumns rowData = demoList.get(rowIndex);
337 | messageLog.writeOutput("Row " + rowIndex + " changed to: " + rowData);
338 | }
339 | }
340 |
341 | public void resetFocus() {
342 | nav.setFocusedCell(0, 1, true);
343 | }
344 |
345 | public void openEditor() {
346 | nav.editRow(1, 3);
347 | }
348 |
349 | }
350 |
--------------------------------------------------------------------------------
/GridFastNavigation-addon/src/main/java/org/vaadin/patrik/client/GridFastNavigationConnector.java:
--------------------------------------------------------------------------------
1 | package org.vaadin.patrik.client;
2 |
3 | import java.util.List;
4 |
5 | import org.vaadin.patrik.FastNavigation;
6 | import org.vaadin.patrik.client.EditorStateManager.EditorListener;
7 | import org.vaadin.patrik.client.FocusTracker.FocusListener;
8 | import org.vaadin.patrik.shared.FastNavigationClientRPC;
9 | import org.vaadin.patrik.shared.FastNavigationServerRPC;
10 | import org.vaadin.patrik.shared.FastNavigationState;
11 |
12 | import com.google.gwt.animation.client.AnimationScheduler;
13 | import com.google.gwt.animation.client.AnimationScheduler.AnimationCallback;
14 | import com.google.gwt.core.client.Scheduler;
15 | import com.google.gwt.dom.client.DivElement;
16 | import com.google.gwt.dom.client.Element;
17 | import com.google.gwt.dom.client.NodeList;
18 | import com.google.gwt.dom.client.Style;
19 | import com.google.gwt.dom.client.TableRowElement;
20 | import com.google.gwt.user.client.Window;
21 | import com.google.gwt.user.client.ui.Widget;
22 | import com.vaadin.client.BrowserInfo;
23 | import com.vaadin.client.ComponentConnector;
24 | import com.vaadin.client.ServerConnector;
25 | import com.vaadin.client.annotations.OnStateChange;
26 | import com.vaadin.client.extensions.AbstractExtensionConnector;
27 | import com.vaadin.client.widgets.Grid;
28 | import com.vaadin.client.widgets.Grid.Editor;
29 | import com.vaadin.shared.ui.Connect;
30 |
31 | @SuppressWarnings("serial")
32 | @Connect(FastNavigation.class)
33 | public class GridFastNavigationConnector extends AbstractExtensionConnector {
34 |
35 | private Grid