]> source.dussan.org Git - vaadin-framework.git/commitdiff
Ensure type safety and serializable nature of all the listeners (#12045)
authorTatu Lund <tatu@vaadin.com>
Fri, 3 Jul 2020 08:39:41 +0000 (11:39 +0300)
committerGitHub <noreply@github.com>
Fri, 3 Jul 2020 08:39:41 +0000 (11:39 +0300)
36 files changed:
compatibility-server/src/main/java/com/vaadin/v7/data/Property.java
compatibility-server/src/main/java/com/vaadin/v7/event/ItemClickEvent.java
compatibility-server/src/main/java/com/vaadin/v7/event/SelectionEvent.java
compatibility-server/src/main/java/com/vaadin/v7/event/SortEvent.java
compatibility-server/src/main/java/com/vaadin/v7/ui/Calendar.java
compatibility-server/src/main/java/com/vaadin/v7/ui/Grid.java
compatibility-server/src/main/java/com/vaadin/v7/ui/Table.java
compatibility-server/src/main/java/com/vaadin/v7/ui/Tree.java
compatibility-server/src/main/java/com/vaadin/v7/ui/Upload.java
compatibility-server/src/main/java/com/vaadin/v7/ui/components/calendar/CalendarComponentEvents.java
compatibility-server/src/main/java/com/vaadin/v7/ui/components/colorpicker/ColorChangeListener.java
server/src/main/java/com/vaadin/data/provider/DataProviderListener.java
server/src/main/java/com/vaadin/event/ContextClickEvent.java
server/src/main/java/com/vaadin/event/EventRouter.java
server/src/main/java/com/vaadin/event/ListenerMethod.java
server/src/main/java/com/vaadin/event/MethodEventSource.java
server/src/main/java/com/vaadin/event/SortEvent.java
server/src/main/java/com/vaadin/event/UIEvents.java
server/src/main/java/com/vaadin/server/AbstractClientConnector.java
server/src/main/java/com/vaadin/server/BootstrapListener.java
server/src/main/java/com/vaadin/server/Page.java
server/src/main/java/com/vaadin/ui/Button.java
server/src/main/java/com/vaadin/ui/HasComponents.java
server/src/main/java/com/vaadin/ui/LoginForm.java
server/src/main/java/com/vaadin/ui/Notification.java
server/src/main/java/com/vaadin/ui/PopupView.java
server/src/main/java/com/vaadin/ui/TabSheet.java
server/src/main/java/com/vaadin/ui/Upload.java
server/src/main/java/com/vaadin/ui/Window.java
server/src/main/java/com/vaadin/ui/components/grid/ColumnReorderListener.java
server/src/main/java/com/vaadin/ui/components/grid/ColumnResizeListener.java
server/src/main/java/com/vaadin/ui/components/grid/ColumnVisibilityChangeListener.java
server/src/main/java/com/vaadin/ui/components/grid/EditorCancelListener.java
server/src/main/java/com/vaadin/ui/components/grid/EditorOpenListener.java
server/src/main/java/com/vaadin/ui/components/grid/EditorSaveListener.java
uitest/src/main/java/com/vaadin/tests/minitutorials/v7a3/Refresher.java

index 8c93e72a799f38fbedbdc27857c89e697bd1f5d0..f9a8da3203efe6aac862e0cfd3eb495c8fb87ad2 100644 (file)
@@ -21,6 +21,7 @@ import java.io.Serializable;
 import com.vaadin.data.Binder;
 import com.vaadin.data.HasValue;
 import com.vaadin.data.ValueProvider;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.Setter;
 
 /**
@@ -281,7 +282,7 @@ public interface Property<T> extends Serializable {
      * @since 3.0
      */
     @Deprecated
-    public interface ValueChangeListener extends Serializable {
+    public interface ValueChangeListener extends SerializableEventListener {
 
         /**
          * Notifies this listener that the Property's value has changed.
@@ -373,7 +374,7 @@ public interface Property<T> extends Serializable {
      * @since 3.0
      */
     @Deprecated
-    public interface ReadOnlyStatusChangeListener extends Serializable {
+    public interface ReadOnlyStatusChangeListener extends SerializableEventListener {
 
         /**
          * Notifies this listener that a Property's read-only status has
index ee7de988bbfd4cfbc03b439b4e6ed21c20304a76..1beb05400ab24f77b187148d8d0413e35d70fa13 100644 (file)
@@ -19,6 +19,7 @@ import java.io.Serializable;
 import java.lang.reflect.Method;
 
 import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.MouseEventDetails;
 import com.vaadin.ui.Component;
 import com.vaadin.v7.data.Container;
@@ -94,7 +95,7 @@ public class ItemClickEvent extends ClickEvent {
     }
 
     @Deprecated
-    public interface ItemClickListener extends Serializable {
+    public interface ItemClickListener extends SerializableEventListener {
         public void itemClick(ItemClickEvent event);
     }
 
index fb4c5917443d5a193a544ae2c42c3f0db77e2a4e..024e5ec6c0a0a05b4e94bfce10b7699e8de49200 100644 (file)
@@ -22,6 +22,8 @@ import java.util.EventObject;
 import java.util.LinkedHashSet;
 import java.util.Set;
 
+import com.vaadin.event.SerializableEventListener;
+
 /**
  * An event that specifies what in a selection has changed, and where the
  * selection took place.
@@ -100,7 +102,7 @@ public class SelectionEvent extends EventObject {
      * SelectionEvents}.
      */
     @Deprecated
-    public interface SelectionListener extends Serializable {
+    public interface SelectionListener extends SerializableEventListener {
         /**
          * Notifies the listener that the selection state has changed.
          *
index e3936dbf90a001c63e712e086e02e8f92876ffd9..cc93c36e4a5664c3401dd2086c3edf656a55ca03 100644 (file)
@@ -18,6 +18,7 @@ package com.vaadin.v7.event;
 import java.io.Serializable;
 import java.util.List;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.Registration;
 import com.vaadin.ui.Component;
 import com.vaadin.v7.data.sort.SortOrder;
@@ -78,7 +79,7 @@ public class SortEvent extends Component.Event {
      */
     @FunctionalInterface
     @Deprecated
-    public interface SortListener extends Serializable {
+    public interface SortListener extends SerializableEventListener {
         /**
          * Called when the sort order has changed.
          *
index f7e98a760a955242c950e88cbc4555ddc69d07dc..66b665dfcd47017ff01125e095db6df9c225ce07 100644 (file)
@@ -43,6 +43,7 @@ import org.jsoup.nodes.Element;
 
 import com.vaadin.event.Action;
 import com.vaadin.event.Action.Handler;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.event.dd.DropHandler;
 import com.vaadin.event.dd.DropTarget;
 import com.vaadin.event.dd.TargetDetails;
@@ -182,7 +183,7 @@ public class Calendar extends AbstractLegacyComponent
     private String weeklyCaptionFormat = null;
 
     /** Map from event ids to event handlers */
-    private final Map<String, EventListener> handlers;
+    private final Map<String, SerializableEventListener> handlers;
 
     /**
      * Drop Handler for Vaadin DD. By default null.
@@ -303,7 +304,7 @@ public class Calendar extends AbstractLegacyComponent
     public Calendar(String caption, CalendarEventProvider eventProvider) {
         registerRpc(rpc);
         setCaption(caption);
-        handlers = new HashMap<String, EventListener>();
+        handlers = new HashMap<String, SerializableEventListener>();
         setDefaultHandlers();
         currentCalendar.setTime(new Date());
         setEventProvider(eventProvider);
@@ -1429,7 +1430,7 @@ public class Calendar extends AbstractLegacyComponent
      *            The method on the lister to call when the event is triggered
      */
     protected void setHandler(String eventId, Class<?> eventType,
-            EventListener listener, Method listenerMethod) {
+            SerializableEventListener listener, Method listenerMethod) {
         if (handlers.get(eventId) != null) {
             removeListener(eventId, eventType, handlers.get(eventId));
             handlers.remove(eventId);
index f67bbb4c3e9739cf827f3863bf6a03f48fdef1a5..f13ea0198f2f388f35beb5486426ae3d77b49cae 100644 (file)
@@ -48,6 +48,7 @@ import com.vaadin.event.FieldEvents.BlurEvent;
 import com.vaadin.event.FieldEvents.BlurListener;
 import com.vaadin.event.FieldEvents.FocusEvent;
 import com.vaadin.event.FieldEvents.FocusListener;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.AbstractClientConnector;
 import com.vaadin.server.AbstractExtension;
 import com.vaadin.server.EncodeResult;
@@ -210,7 +211,7 @@ public class Grid extends AbstractComponent
      * @since 7.5.0
      */
     @Deprecated
-    public interface ColumnVisibilityChangeListener extends Serializable {
+    public interface ColumnVisibilityChangeListener extends SerializableEventListener {
         /**
          * Called when a column has become hidden or unhidden.
          *
@@ -831,7 +832,7 @@ public class Grid extends AbstractComponent
      * @since 7.5.0
      */
     @Deprecated
-    public interface ColumnReorderListener extends Serializable {
+    public interface ColumnReorderListener extends SerializableEventListener {
 
         /**
          * Called when the columns of the grid have been reordered.
@@ -883,7 +884,7 @@ public class Grid extends AbstractComponent
      * @since 7.6
      */
     @Deprecated
-    public interface ColumnResizeListener extends Serializable {
+    public interface ColumnResizeListener extends SerializableEventListener {
 
         /**
          * Called when the columns of the grid have been resized.
index 0519e20f75e866f09a8f509c6b93e1df0cc27191..2cd3ad075ead9f950d8dacf06d838778b07c0656 100644 (file)
@@ -41,6 +41,7 @@ import com.vaadin.event.Action;
 import com.vaadin.event.Action.Handler;
 import com.vaadin.event.ContextClickEvent;
 import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.event.dd.DragAndDropEvent;
 import com.vaadin.event.dd.DragSource;
 import com.vaadin.event.dd.DropHandler;
@@ -5430,7 +5431,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * headerClick method is called when the user presses a header column cell.
      */
     @Deprecated
-    public interface HeaderClickListener extends Serializable {
+    public interface HeaderClickListener extends SerializableEventListener {
 
         /**
          * Called when a user clicks a header column cell.
@@ -5447,7 +5448,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * footerClick method is called when the user presses a footer column cell.
      */
     @Deprecated
-    public interface FooterClickListener extends Serializable {
+    public interface FooterClickListener extends SerializableEventListener {
 
         /**
          * Called when a user clicks a footer column cell.
@@ -5684,7 +5685,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * Interface for listening to column resize events.
      */
     @Deprecated
-    public interface ColumnResizeListener extends Serializable {
+    public interface ColumnResizeListener extends SerializableEventListener {
 
         /**
          * This method is triggered when the column has been resized.
@@ -5773,7 +5774,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * Interface for listening to column reorder events.
      */
     @Deprecated
-    public interface ColumnReorderListener extends Serializable {
+    public interface ColumnReorderListener extends SerializableEventListener {
 
         /**
          * This method is triggered when the column has been reordered.
@@ -5825,7 +5826,7 @@ public class Table extends AbstractSelect implements Action.Container,
      * @since 7.6
      */
     @Deprecated
-    public interface ColumnCollapseListener extends Serializable {
+    public interface ColumnCollapseListener extends SerializableEventListener {
 
         /**
          * This method is triggered when the collapse state for a column has
index 3a282b02333cf6cf9ced9642f75076628e373a9d..806e16593e4e4deb7179b8b8546f24b2fa681582 100644 (file)
@@ -36,6 +36,7 @@ import org.jsoup.nodes.Element;
 import com.vaadin.event.Action;
 import com.vaadin.event.Action.Handler;
 import com.vaadin.event.ContextClickEvent;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.event.Transferable;
 import com.vaadin.event.dd.DragAndDropEvent;
 import com.vaadin.event.dd.DragSource;
@@ -1054,7 +1055,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
      * @since 3.0
      */
     @Deprecated
-    public interface ExpandListener extends Serializable {
+    public interface ExpandListener extends SerializableEventListener {
 
         public static final Method EXPAND_METHOD = ReflectTools.findMethod(
                 ExpandListener.class, "nodeExpand", ExpandEvent.class);
@@ -1159,7 +1160,7 @@ public class Tree extends AbstractSelect implements Container.Hierarchical,
      * @since 3.0
      */
     @Deprecated
-    public interface CollapseListener extends Serializable {
+    public interface CollapseListener extends SerializableEventListener {
 
         public static final Method COLLAPSE_METHOD = ReflectTools.findMethod(
                 CollapseListener.class, "nodeCollapse", CollapseEvent.class);
index f7c080b4c0f831f553240e3b80c08f560b05f713..189100f611657718d15dba3ea9ae130da1ab515f 100644 (file)
@@ -23,6 +23,7 @@ import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.Map;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.NoInputStreamException;
 import com.vaadin.server.NoOutputStreamException;
 import com.vaadin.server.PaintException;
@@ -555,7 +556,7 @@ public class Upload extends AbstractLegacyComponent
      * @since 5.0
      */
     @Deprecated
-    public interface StartedListener extends Serializable {
+    public interface StartedListener extends SerializableEventListener {
 
         /**
          * Upload has started.
@@ -573,7 +574,7 @@ public class Upload extends AbstractLegacyComponent
      * @since 3.0
      */
     @Deprecated
-    public interface FinishedListener extends Serializable {
+    public interface FinishedListener extends SerializableEventListener {
 
         /**
          * Upload has finished.
@@ -591,7 +592,7 @@ public class Upload extends AbstractLegacyComponent
      * @since 3.0
      */
     @Deprecated
-    public interface FailedListener extends Serializable {
+    public interface FailedListener extends SerializableEventListener {
 
         /**
          * Upload has finished unsuccessfully.
@@ -609,7 +610,7 @@ public class Upload extends AbstractLegacyComponent
      * @since 3.0
      */
     @Deprecated
-    public interface SucceededListener extends Serializable {
+    public interface SucceededListener extends SerializableEventListener {
 
         /**
          * Upload successful.
@@ -626,7 +627,7 @@ public class Upload extends AbstractLegacyComponent
      * @since 7.2
      */
     @Deprecated
-    public interface ChangeListener extends Serializable {
+    public interface ChangeListener extends SerializableEventListener {
 
         Method FILENAME_CHANGED = ReflectTools.findMethod(ChangeListener.class,
                 "filenameChanged", ChangeEvent.class);
index cf2337274cd9bcfc4bf9a5dcc3799038cad59243..cc04ac15d95fea81447afd948fc588d6ba846fab 100644 (file)
@@ -20,6 +20,7 @@ import java.lang.reflect.Method;
 import java.util.Date;
 import java.util.EventListener;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.util.ReflectTools;
 import com.vaadin.v7.shared.ui.calendar.CalendarEventId;
 import com.vaadin.v7.ui.Calendar;
@@ -123,7 +124,7 @@ public interface CalendarComponentEvents extends Serializable {
      *
      */
     @Deprecated
-    public interface EventMoveHandler extends EventListener, Serializable {
+    public interface EventMoveHandler extends SerializableEventListener {
 
         /** Trigger method for the MoveEvent. */
         public static final Method eventMoveMethod = ReflectTools.findMethod(
@@ -231,7 +232,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** RangeSelectHandler handles RangeSelectEvent. */
     @Deprecated
-    public interface RangeSelectHandler extends EventListener, Serializable {
+    public interface RangeSelectHandler extends SerializableEventListener {
 
         /** Trigger method for the RangeSelectEvent. */
         public static final Method rangeSelectMethod = ReflectTools.findMethod(
@@ -314,7 +315,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** ForwardHandler handles ForwardEvent. */
     @Deprecated
-    public interface ForwardHandler extends EventListener, Serializable {
+    public interface ForwardHandler extends SerializableEventListener {
 
         /** Trigger method for the ForwardEvent. */
         public static final Method forwardMethod = ReflectTools.findMethod(
@@ -351,7 +352,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** BackwardHandler handles BackwardEvent. */
     @Deprecated
-    public interface BackwardHandler extends EventListener, Serializable {
+    public interface BackwardHandler extends SerializableEventListener {
 
         /** Trigger method for the BackwardEvent. */
         public static final Method backwardMethod = ReflectTools.findMethod(
@@ -396,7 +397,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** DateClickHandler handles DateClickEvent. */
     @Deprecated
-    public interface DateClickHandler extends EventListener, Serializable {
+    public interface DateClickHandler extends SerializableEventListener {
 
         /** Trigger method for the DateClickEvent. */
         public static final Method dateClickMethod = ReflectTools.findMethod(
@@ -441,7 +442,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** EventClickHandler handles EventClick. */
     @Deprecated
-    public interface EventClickHandler extends EventListener, Serializable {
+    public interface EventClickHandler extends SerializableEventListener {
 
         /** Trigger method for the EventClick. */
         public static final Method eventClickMethod = ReflectTools.findMethod(
@@ -510,7 +511,7 @@ public interface CalendarComponentEvents extends Serializable {
 
     /** WeekClickHandler handles WeekClicks. */
     @Deprecated
-    public interface WeekClickHandler extends EventListener, Serializable {
+    public interface WeekClickHandler extends SerializableEventListener {
 
         /** Trigger method for the WeekClick. */
         public static final Method weekClickMethod = ReflectTools.findMethod(
@@ -615,7 +616,7 @@ public interface CalendarComponentEvents extends Serializable {
      * Handler for EventResize event.
      */
     @Deprecated
-    public interface EventResizeHandler extends EventListener, Serializable {
+    public interface EventResizeHandler extends SerializableEventListener {
 
         /** Trigger method for the EventResize. */
         public static final Method eventResizeMethod = ReflectTools.findMethod(
index 1077a2b7d95911cc736bdcf0472535187ee3a52c..2153a9e89580cae3c28f77c3ce48626671afee1d 100644 (file)
@@ -15,7 +15,7 @@
  */
 package com.vaadin.v7.ui.components.colorpicker;
 
-import java.io.Serializable;
+import com.vaadin.event.SerializableEventListener;
 
 /**
  * The listener interface for receiving colorChange events. The class that is
@@ -30,7 +30,7 @@ import java.io.Serializable;
  * @see ColorChangeEvent
  */
 @Deprecated
-public interface ColorChangeListener extends Serializable {
+public interface ColorChangeListener extends SerializableEventListener {
 
     /**
      * Called when a new color has been selected.
index 4ee35013f9dad9dc4ece76a75bafdd5e631baec6..a5b68238082e3f097f72c78624a8b6a5e0bb6220 100644 (file)
@@ -15,7 +15,7 @@
  */
 package com.vaadin.data.provider;
 
-import java.io.Serializable;
+import com.vaadin.event.SerializableEventListener;
 
 /**
  * Interface for listening for a data change events fired by a
@@ -28,7 +28,7 @@ import java.io.Serializable;
  *            the data type
  */
 @FunctionalInterface
-public interface DataProviderListener<T> extends Serializable {
+public interface DataProviderListener<T> extends SerializableEventListener {
 
     /**
      * Invoked when this listener receives a data change event from a data
index c9ed77f0012e14e0cca7adcf8f1a77ed6b7f5541..774b17f8f8a316392e4158c0bce6a7552f4d55d4 100644 (file)
@@ -46,7 +46,7 @@ public class ContextClickEvent extends ClickEvent {
      * Listener for {@link ContextClickEvent ContextClickEvents}.
      */
     @FunctionalInterface
-    public interface ContextClickListener extends Serializable {
+    public interface ContextClickListener extends SerializableEventListener {
 
         /**
          * Called when the context click happens.
index 34f71afb21ceb36a5a4eba959ce5a356dbf4326f..d1164c0542ada5109110d28b63a0fd96f0d9d0f0 100644 (file)
@@ -24,6 +24,8 @@ import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Objects;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import com.vaadin.server.ErrorEvent;
 import com.vaadin.server.ErrorHandler;
@@ -52,10 +54,13 @@ public class EventRouter implements MethodEventSource {
      * events generated by this component. Don't add a JavaDoc comment here, we
      * use the default documentation from implemented interface.
      */
+    @Deprecated
     @Override
     public Registration addListener(Class<?> eventType, Object object,
             Method method) {
         Objects.requireNonNull(object, "Listener must not be null.");
+        getLogger().log(Level.WARNING, "Adding listeners with type Object is"
+                + " deprecated, event listener should extend SerializableEventListener");
         if (listenerList == null) {
             listenerList = new LinkedHashSet<>();
         }
@@ -65,6 +70,24 @@ public class EventRouter implements MethodEventSource {
         return () -> listenerList.remove(listenerMethod);
     }
 
+    /*
+     * Registers a new listener with the specified activation method to listen
+     * events generated by this component. Don't add a JavaDoc comment here, we
+     * use the default documentation from implemented interface.
+     */
+    @Override
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, Method method) {
+        Objects.requireNonNull(listener, "Listener must not be null.");
+        if (listenerList == null) {
+            listenerList = new LinkedHashSet<>();
+        }
+        ListenerMethod listenerMethod = new ListenerMethod(eventType, listener,
+                method);
+        listenerList.add(listenerMethod);
+        return () -> listenerList.remove(listenerMethod);
+    }
+
     /**
      * Registers a new event listener with the specified activation method to
      * listen events generated by this component. If the activation method does
@@ -87,7 +110,11 @@ public class EventRouter implements MethodEventSource {
      * For more information on the inheritable event mechanism see the
      * {@link com.vaadin.event com.vaadin.event package documentation}.
      * </p>
-     *
+     * 
+     * @deprecated As of 8.12. Use
+     *             {@link #addListener(Class, SerializableEventListener, Method, String, SharedState)}
+     *             instead
+     * 
      * @param eventType
      *            the type of the listened event. Events of this type or its
      *            subclasses activate the listener.
@@ -106,9 +133,11 @@ public class EventRouter implements MethodEventSource {
      *             if {@code target} is {@code null}
      * @since 8.2
      */
+    @Deprecated
     public Registration addListener(Class<?> eventType, Object target,
             Method method, String eventIdentifier, SharedState state) {
-        Objects.requireNonNull(target, "Listener must not be null.");
+        getLogger().log(Level.WARNING, "Adding listeners with type Object is"
+                + " deprecated, event listener should extend SerializableEventListener");
         if (listenerList == null) {
             listenerList = new LinkedHashSet<>();
         }
@@ -127,15 +156,80 @@ public class EventRouter implements MethodEventSource {
         };
     }
 
+    /**
+     * Registers a new event listener with the specified activation method to
+     * listen events generated by this component. If the activation method does
+     * not have any arguments the event object will not be passed to it when
+     * it's called.
+     *
+     * <p>
+     * This method additionally informs the event-api to stop routing events
+     * with the given {@code eventIdentifier} to the components handleEvent
+     * function call.
+     * </p>
+     *
+     * <p>
+     * The only way to remove the listener is to use the returned
+     * {@link Registration}. The other methods, e.g.
+     * {@link #removeAllListeners()} do not do that.
+     * </p>
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the listener instance who owns the activation method.
+     * @param method
+     *            the activation method.
+     * @param eventIdentifier
+     *            the identifier of the event to listen for
+     * @param state
+     *            The component State
+     * @return a registration object for removing the listener
+     * @throws IllegalArgumentException
+     *             unless {@code method} has exactly one match in {@code target}
+     * @throws NullPointerException
+     *             if {@code target} is {@code null}
+     * @since 8.12
+     */
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, Method method,
+            String eventIdentifier, SharedState state) {
+        if (listenerList == null) {
+            listenerList = new LinkedHashSet<>();
+        }
+        ListenerMethod listenerMethod = new ListenerMethod(eventType, listener,
+                method);
+        listenerList.add(listenerMethod);
+
+        Registration registration = ComponentStateUtil
+                .addRegisteredEventListener(state, eventIdentifier);
+
+        return () -> {
+            listenerList.remove(listenerMethod);
+            if (!hasListeners(eventType)) {
+                registration.remove();
+            }
+        };
+    }
+
     /*
      * Registers a new listener with the specified named activation method to
      * listen events generated by this component. Don't add a JavaDoc comment
      * here, we use the default documentation from implemented interface.
      */
+    @Deprecated
     @Override
     public Registration addListener(Class<?> eventType, Object object,
             String methodName) {
         Objects.requireNonNull(object, "Listener must not be null.");
+        getLogger().log(Level.WARNING, "Adding listeners with type Object is"
+                + " deprecated, event listener should extend SerializableEventListener");
         if (listenerList == null) {
             listenerList = new LinkedHashSet<>();
         }
@@ -145,12 +239,31 @@ public class EventRouter implements MethodEventSource {
         return () -> listenerList.remove(listenerMethod);
     }
 
+    /*
+     * Registers a new listener with the specified named activation method to
+     * listen events generated by this component. Don't add a JavaDoc comment
+     * here, we use the default documentation from implemented interface.
+     */
+    @Override
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, String methodName) {
+        Objects.requireNonNull(listener, "Listener must not be null.");
+        if (listenerList == null) {
+            listenerList = new LinkedHashSet<>();
+        }
+        ListenerMethod listenerMethod = new ListenerMethod(eventType, listener,
+                methodName);
+        listenerList.add(listenerMethod);
+        return () -> listenerList.remove(listenerMethod);
+    }
+
     /*
      * Removes all registered listeners matching the given parameters. Don't add
      * a JavaDoc comment here, we use the default documentation from implemented
      * interface.
      */
     @Override
+    @Deprecated
     public void removeListener(Class<?> eventType, Object target) {
         if (listenerList != null) {
             final Iterator<ListenerMethod> i = listenerList.iterator();
@@ -164,12 +277,24 @@ public class EventRouter implements MethodEventSource {
         }
     }
 
+    /*
+     * Removes all registered listeners matching the given parameters. Don't add
+     * a JavaDoc comment here, we use the default documentation from implemented
+     * interface.
+     */
+    @Override
+    public void removeListener(Class<?> eventType,
+            SerializableEventListener listener) {
+        removeListener(eventType, (Object) listener);
+    }
+
     /*
      * Removes the event listener methods matching the given given parameters.
      * Don't add a JavaDoc comment here, we use the default documentation from
      * implemented interface.
      */
     @Override
+    @Deprecated
     public void removeListener(Class<?> eventType, Object target,
             Method method) {
         if (listenerList != null) {
@@ -190,6 +315,7 @@ public class EventRouter implements MethodEventSource {
      * implemented interface.
      */
     @Override
+    @Deprecated
     public void removeListener(Class<?> eventType, Object target,
             String methodName) {
 
@@ -314,4 +440,8 @@ public class EventRouter implements MethodEventSource {
         }
         return listeners;
     }
+
+    private static final Logger getLogger() {
+        return Logger.getLogger(EventRouter.class.getName());
+    }
 }
index 0648d2741f3649efcc81b737a23c8e706ebe89f8..e83efd477539a214ce18ce8162ab0866f8e47d00 100644 (file)
@@ -171,9 +171,9 @@ public class ListenerMethod implements EventListener, Serializable {
      *            will not be passed to the trigger method, though it is still
      *            called.
      * @throws IllegalArgumentException
-     *             if <code>method</code> is not a member of <code>target</code>
-     *             .
+     *             if <code>method</code> is not a member of <code>target</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, Method method,
             Object[] arguments, int eventArgumentIndex)
             throws IllegalArgumentException {
@@ -207,6 +207,45 @@ public class ListenerMethod implements EventListener, Serializable {
         this.eventArgumentIndex = eventArgumentIndex;
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from a trigger method, it's arguments and
+     * the argument index specifying which one is replaced with the event object
+     * when the trigger method is called.
+     * </p>
+     *
+     * <p>
+     * This constructor gets the trigger method as a parameter so it does not
+     * need to reflect to find it out.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method
+     * @param method
+     *            the trigger method
+     * @param arguments
+     *            the arguments to be passed to the trigger method
+     * @param eventArgumentIndex
+     *            An index to the argument list. This index points out the
+     *            argument that is replaced with the event object before the
+     *            argument set is passed to the trigger method. If the
+     *            eventArgumentIndex is negative, the triggering event object
+     *            will not be passed to the trigger method, though it is still
+     *            called.
+     * @throws IllegalArgumentException
+     *             if <code>method</code> is not a member of <code>target</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, Method method,
+            Object[] arguments, int eventArgumentIndex)
+            throws IllegalArgumentException {
+        this(eventType, (Object) listener, method, arguments,
+                eventArgumentIndex);
+    }
+
     /**
      * <p>
      * Constructs a new event listener from a trigger method name, it's
@@ -238,6 +277,7 @@ public class ListenerMethod implements EventListener, Serializable {
      *             unless exactly one match <code>methodName</code> is found in
      *             <code>target</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, String methodName,
             Object[] arguments, int eventArgumentIndex)
             throws IllegalArgumentException {
@@ -275,6 +315,45 @@ public class ListenerMethod implements EventListener, Serializable {
         this.eventArgumentIndex = eventArgumentIndex;
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from a trigger method name, it's
+     * arguments and the argument index specifying which one is replaced with
+     * the event object. The actual trigger method is reflected from
+     * <code>object</code>, and <code>java.lang.IllegalArgumentException</code>
+     * is thrown unless exactly one match is found.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method.
+     * @param methodName
+     *            the name of the trigger method. If the object does not contain
+     *            the method or it contains more than one matching methods
+     *            <code>java.lang.IllegalArgumentException</code> is thrown.
+     * @param arguments
+     *            the arguments to be passed to the trigger method.
+     * @param eventArgumentIndex
+     *            An index to the argument list. This index points out the
+     *            argument that is replaced with the event object before the
+     *            argument set is passed to the trigger method. If the
+     *            eventArgumentIndex is negative, the triggering event object
+     *            will not be passed to the trigger method, though it is still
+     *            called.
+     * @throws IllegalArgumentException
+     *             unless exactly one match <code>methodName</code> is found in
+     *             <code>target</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, String methodName,
+            Object[] arguments, int eventArgumentIndex)
+            throws IllegalArgumentException {
+        this(eventType, (Object) listener, methodName, arguments,
+                eventArgumentIndex);
+    }
+
     /**
      * <p>
      * Constructs a new event listener from the trigger method and it's
@@ -298,9 +377,9 @@ public class ListenerMethod implements EventListener, Serializable {
      * @param arguments
      *            the arguments to be passed to the trigger method.
      * @throws IllegalArgumentException
-     *             if <code>method</code> is not a member of <code>target</code>
-     *             .
+     *             if <code>method</code> is not a member of <code>target</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, Method method,
             Object[] arguments) throws IllegalArgumentException {
 
@@ -318,6 +397,37 @@ public class ListenerMethod implements EventListener, Serializable {
         eventArgumentIndex = -1;
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from the trigger method and it's
+     * arguments. Since the the index to the replaced parameter is not specified
+     * the event triggering this listener will not be passed to the trigger
+     * method.
+     * </p>
+     *
+     * <p>
+     * This constructor gets the trigger method as a parameter so it does not
+     * need to reflect to find it out.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method.
+     * @param method
+     *            the trigger method.
+     * @param arguments
+     *            the arguments to be passed to the trigger method.
+     * @throws IllegalArgumentException
+     *             if <code>method</code> is not a member of <code>target</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, Method method,
+            Object[] arguments) throws IllegalArgumentException {
+        this(eventType, (Object) listener, method, arguments);
+    }
+
     /**
      * <p>
      * Constructs a new event listener from a trigger method name and it's
@@ -347,6 +457,7 @@ public class ListenerMethod implements EventListener, Serializable {
      *             unless exactly one match <code>methodName</code> is found in
      *             <code>object</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, String methodName,
             Object[] arguments) throws IllegalArgumentException {
 
@@ -368,6 +479,41 @@ public class ListenerMethod implements EventListener, Serializable {
         eventArgumentIndex = -1;
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from a trigger method name and it's
+     * arguments. Since the the index to the replaced parameter is not specified
+     * the event triggering this listener will not be passed to the trigger
+     * method.
+     * </p>
+     *
+     * <p>
+     * The actual trigger method is reflected from <code>listener</code>, and
+     * <code>java.lang.IllegalArgumentException</code> is thrown unless exactly
+     * one match is found.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method.
+     * @param methodName
+     *            the name of the trigger method. If the object does not contain
+     *            the method or it contains more than one matching methods
+     *            <code>java.lang.IllegalArgumentException</code> is thrown.
+     * @param arguments
+     *            the arguments to be passed to the trigger method.
+     * @throws IllegalArgumentException
+     *             unless exactly one match <code>methodName</code> is found in
+     *             <code>object</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, String methodName,
+            Object[] arguments) throws IllegalArgumentException {
+        this(eventType, (Object) listener, methodName, arguments);
+    }
+
     /**
      * <p>
      * Constructs a new event listener from a trigger method. Since the argument
@@ -388,9 +534,9 @@ public class ListenerMethod implements EventListener, Serializable {
      * @param method
      *            the trigger method.
      * @throws IllegalArgumentException
-     *             if <code>method</code> is not a member of <code>object</code>
-     *             .
+     *             if <code>method</code> is not a member of <code>object</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, Method method)
             throws IllegalArgumentException {
 
@@ -420,6 +566,34 @@ public class ListenerMethod implements EventListener, Serializable {
         }
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from a trigger method. Since the argument
+     * list is unspecified no parameters are passed to the trigger method when
+     * the listener is triggered.
+     * </p>
+     *
+     * <p>
+     * This constructor gets the trigger method as a parameter so it does not
+     * need to reflect to find it out.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method.
+     * @param method
+     *            the trigger method.
+     * @throws IllegalArgumentException
+     *             if <code>method</code> is not a member of <code>object</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, Method method)
+            throws IllegalArgumentException {
+        this(eventType, (Object) listener, method);
+    }
+
     /**
      * <p>
      * Constructs a new event listener from a trigger method name. Since the
@@ -446,6 +620,7 @@ public class ListenerMethod implements EventListener, Serializable {
      *             unless exactly one match <code>methodName</code> is found in
      *             <code>target</code>.
      */
+    @Deprecated
     public ListenerMethod(Class<?> eventType, Object target, String methodName)
             throws IllegalArgumentException {
 
@@ -479,6 +654,38 @@ public class ListenerMethod implements EventListener, Serializable {
         }
     }
 
+    /**
+     * <p>
+     * Constructs a new event listener from a trigger method name. Since the
+     * argument list is unspecified no parameters are passed to the trigger
+     * method when the listener is triggered.
+     * </p>
+     *
+     * <p>
+     * The actual trigger method is reflected from <code>listener</code>, and
+     * <code>java.lang.IllegalArgumentException</code> is thrown unless exactly
+     * one match is found.
+     * </p>
+     *
+     * @param eventType
+     *            the event type that is listener listens to. All events of this
+     *            kind (or its subclasses) result in calling the trigger method.
+     * @param listener
+     *            the listener instance that contains the trigger method.
+     * @param methodName
+     *            the name of the trigger method. If the object does not contain
+     *            the method or it contains more than one matching methods
+     *            <code>java.lang.IllegalArgumentException</code> is thrown.
+     * @throws IllegalArgumentException
+     *             unless exactly one match <code>methodName</code> is found in
+     *             <code>target</code>.
+     */
+    public ListenerMethod(Class<?> eventType,
+            SerializableEventListener listener, String methodName)
+            throws IllegalArgumentException {
+        this(eventType, (Object) listener, methodName);
+    }
+
     /**
      * Receives one event from the <code>EventRouter</code> and calls the
      * trigger method if it matches with the criteria defined for the listener.
@@ -555,7 +762,7 @@ public class ListenerMethod implements EventListener, Serializable {
      * @return <code>true</code> if <code>target</code> is the same object as
      *         the one stored in this object, <code>eventType</code> equals with
      *         the event type stored in this object and <code>method</code>
-     *         equals with the method stored in this object
+     *         equals with the method stored in this object.
      */
     public boolean matches(Class<?> eventType, Object target, Method method) {
         return (this.target == target) && (eventType.equals(this.eventType)
index 33e61b842e0f7d3239cfa526aec0391a2cd09b16..a4dfa893329868eec34aec71240334ad83acf18b 100644 (file)
@@ -62,9 +62,39 @@ public interface MethodEventSource extends Serializable {
      *             if {@code object} is {@code null}
      * @since 8.0
      */
+    @Deprecated
     public Registration addListener(Class<?> eventType, Object object,
             Method method);
 
+    /**
+     * Registers a new event listener with the specified activation method to
+     * listen events generated by this component. If the activation method does
+     * not have any arguments the event object will not be passed to it when
+     * it's called.
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the listener instance who owns the activation method.
+     * @param method
+     *            the activation method.
+     * @return a registration object for removing the listener
+     * @throws IllegalArgumentException
+     *             unless <code>method</code> has exactly one match in
+     *             <code>object</code>
+     * @throws NullPointerException
+     *             if {@code object} is {@code null}
+     * @since 8.12
+     */
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, Method method);
+
     /**
      * Registers a new listener with the specified activation method to listen
      * events generated by this component. If the activation method does not
@@ -98,9 +128,46 @@ public interface MethodEventSource extends Serializable {
      *             if {@code object} is {@code null}
      * @since 8.0
      */
+    @Deprecated
     public Registration addListener(Class<?> eventType, Object object,
             String methodName);
 
+    /**
+     * Registers a new listener with the specified activation method to listen
+     * events generated by this component. If the activation method does not
+     * have any arguments the event object will not be passed to it when it's
+     * called.
+     *
+     * <p>
+     * This version of <code>addListener</code> gets the name of the activation
+     * method as a parameter. The actual method is reflected from
+     * <code>listener</code>, and unless exactly one match is found,
+     * <code>java.lang.IllegalArgumentException</code> is thrown.
+     * </p>
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the listener instance who owns the activation method.
+     * @param methodName
+     *            the name of the activation method.
+     * @return a registration object for removing the listener
+     * @throws IllegalArgumentException
+     *             unless <code>method</code> has exactly one match in
+     *             <code>object</code>
+     * @throws NullPointerException
+     *             if {@code object} is {@code null}
+     * @since 8.12
+     */
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener object, String methodName);
+
     /**
      * Removes all registered listeners matching the given parameters. Since
      * this method receives the event type and the listener object as
@@ -119,8 +186,31 @@ public interface MethodEventSource extends Serializable {
      *            the target object that has registered to listen to events of
      *            type <code>eventType</code> with one or more methods.
      */
+    @Deprecated
     public void removeListener(Class<?> eventType, Object target);
 
+    /**
+     * Removes all registered listeners matching the given parameters. Since
+     * this method receives the event type and the listener object as
+     * parameters, it will unregister all <code>object</code>'s methods that are
+     * registered to listen to events of type <code>eventType</code> generated
+     * by this component.
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the exact event type the <code>object</code> listens to.
+     * @param listener
+     *            the listener that has registered to listen to events of type
+     *            <code>eventType</code> with one or more methods.
+     * @since 8.12
+     */
+    public void removeListener(Class<?> eventType,
+            SerializableEventListener listener);
+
     /**
      * Removes one registered listener method. The given method owned by the
      * given object will no longer be called when the specified events are
index dc3211bda715fbeb95eddf12dc5a8bb40e99383c..ace8683959295b928e8cc506e4e1a7865bb4d3ee 100644 (file)
@@ -80,7 +80,7 @@ public class SortEvent<T extends SortOrder<?>> extends Component.Event
      *            the type of the sorting information
      */
     @FunctionalInterface
-    public interface SortListener<T extends SortOrder<?>> extends Serializable {
+    public interface SortListener<T extends SortOrder<?>> extends SerializableEventListener {
         /**
          * Called when the sort order has changed.
          *
index db282917d8935cfe82d1048635b2fcaf232bf869..5f754c85183e277671f1f217db61d227cefd71cc 100644 (file)
@@ -40,7 +40,7 @@ public interface UIEvents {
      * @author Vaadin Ltd
      */
     @FunctionalInterface
-    public interface PollListener extends Serializable {
+    public interface PollListener extends SerializableEventListener {
         public static final Method POLL_METHOD = ReflectTools
                 .findMethod(PollListener.class, "poll", PollEvent.class);
 
index 912aa5b10b8caec20b13a4dac0fd32451af0df98..fe167364650e825c4e6b91255b4c0df49ee3792c 100644 (file)
@@ -34,6 +34,7 @@ import java.util.WeakHashMap;
 
 import com.vaadin.event.EventRouter;
 import com.vaadin.event.MethodEventSource;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.Registration;
 import com.vaadin.shared.communication.ClientRpc;
 import com.vaadin.shared.communication.ServerRpc;
@@ -720,8 +721,6 @@ public abstract class AbstractClientConnector
         }
     }
 
-    /* Listener code starts. Should be refactored. */
-
     /**
      * Registers a new listener with the specified activation method to listen
      * events generated by this component. If the activation method does not
@@ -737,6 +736,10 @@ public abstract class AbstractClientConnector
      * For more information on the inheritable event mechanism see the
      * {@link com.vaadin.event com.vaadin.event package documentation}.
      * </p>
+     * 
+     * @deprecated As of 8.12. Use strongly typed
+     *             {@link #addListener(String, Class, SerializableEventListener, Method)}
+     *             method instead.
      *
      * @param eventIdentifier
      *            the identifier of the event to listen for
@@ -750,6 +753,7 @@ public abstract class AbstractClientConnector
      * @return a registration object for removing the listener
      * @since 8.0
      */
+    @Deprecated
     protected Registration addListener(String eventIdentifier,
             Class<?> eventType, Object target, Method method) {
         if (eventRouter == null) {
@@ -759,6 +763,44 @@ public abstract class AbstractClientConnector
                 eventIdentifier, getState());
     }
 
+    /**
+     * Registers a new listener with the specified activation method to listen
+     * events generated by this component. If the activation method does not
+     * have any arguments the event object will not be passed to it when it's
+     * called.
+     *
+     * <p>
+     * This method additionally informs the event-api to route events with the
+     * given eventIdentifier to the components handleEvent function call.
+     * </p>
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventIdentifier
+     *            the identifier of the event to listen for
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the listener instance who owns the activation method.
+     * @param method
+     *            the activation method.
+     * @return a registration object for removing the listener
+     * @since 8.12
+     */
+    protected Registration addListener(String eventIdentifier,
+            Class<?> eventType, SerializableEventListener listener,
+            Method method) {
+        if (eventRouter == null) {
+            eventRouter = new EventRouter();
+        }
+        return eventRouter.addListener(eventType, listener, method,
+                eventIdentifier, getState());
+    }
+
     /**
      * Checks if the given {@link Event} type is listened for this component.
      *
@@ -823,6 +865,10 @@ public abstract class AbstractClientConnector
      * For more information on the inheritable event mechanism see the
      * {@link com.vaadin.event com.vaadin.event package documentation}.
      * </p>
+     * 
+     * @deprecated As of 8.12. Use strongly typed
+     *             {@link #addListener(Class, SerializableEventListener, Method)}
+     *             method instead.
      *
      * @param eventType
      *            the type of the listened event. Events of this type or its
@@ -834,6 +880,7 @@ public abstract class AbstractClientConnector
      * @return a registration object for removing the listener
      */
     @Override
+    @Deprecated
     public Registration addListener(Class<?> eventType, Object target,
             Method method) {
         if (eventRouter == null) {
@@ -842,6 +889,37 @@ public abstract class AbstractClientConnector
         return eventRouter.addListener(eventType, target, method);
     }
 
+    /**
+     * Registers a new listener with the specified activation method to listen
+     * events generated by this component. If the activation method does not
+     * have any arguments the event object will not be passed to it when it's
+     * called.
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the listener instance who owns the activation method.
+     * @param method
+     *            the activation method.
+     * @return a registration object for removing the listener
+     * @since 8.12
+     */
+
+    @Override
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, Method method) {
+        if (eventRouter == null) {
+            eventRouter = new EventRouter();
+        }
+        return eventRouter.addListener(eventType, listener, method);
+    }
+
     /**
      * Convenience method for registering a new listener with the specified
      * activation method to listen events generated by this component. If the
@@ -874,8 +952,10 @@ public abstract class AbstractClientConnector
      *            the name of the activation method.
      * @return a registration object for removing the listener
      * @deprecated As of 7.0. This method should be avoided. Use
-     *             {@link #addListener(Class, Object, Method)} or
-     *             {@link #addListener(String, Class, Object, Method)} instead.
+     *             {@link #addListener(Class, SerializableEventListener, Method)}
+     *             or
+     *             {@link #addListener(String, Class, SerializableEventListener, Method)}
+     *             instead.
      * @since 8.0
      */
     @Override
@@ -888,6 +968,56 @@ public abstract class AbstractClientConnector
         return eventRouter.addListener(eventType, target, methodName);
     }
 
+    /**
+     * Convenience method for registering a new listener with the specified
+     * activation method to listen events generated by this component. If the
+     * activation method does not have any arguments the event object will not
+     * be passed to it when it's called.
+     *
+     * <p>
+     * This version of <code>addListener</code> gets the name of the activation
+     * method as a parameter. The actual method is reflected from
+     * <code>object</code>, and unless exactly one match is found,
+     * <code>java.lang.IllegalArgumentException</code> is thrown.
+     * </p>
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * <p>
+     * Note: Using this method is discouraged because it cannot be checked
+     * during compilation. Use {@link #addListener(Class, Object, Method)} or
+     * {@link #addListener(String, Class, Object, Method) instead. </p>
+     *
+     * @param eventType
+     *            the type of the listened event. Events of this type or its
+     *            subclasses activate the listener.
+     * @param listener
+     *            the object instance who owns the activation method.
+     * @param methodName
+     *            the name of the activation method.
+     * @return a registration object for removing the listener
+     * @deprecated This method has only been added for ease of migration and
+     *             should be avoided in new code.
+     *             Use
+     *             {@link #addListener(Class, SerializableEventListener, Method)}
+     *             or
+     *             {@link #addListener(String, Class, SerializableEventListener, Method)}
+     *             instead.
+     * @since 8.12
+     */
+    @Override
+    @Deprecated
+    public Registration addListener(Class<?> eventType,
+            SerializableEventListener listener, String methodName) {
+        if (eventRouter == null) {
+            eventRouter = new EventRouter();
+        }
+        return eventRouter.addListener(eventType, listener, methodName);
+    }
+
     /**
      * Removes all registered listeners matching the given parameters. Since
      * this method receives the event type and the listener object as
@@ -916,6 +1046,36 @@ public abstract class AbstractClientConnector
         }
     }
 
+    /**
+     * Removes all registered listeners matching the given parameters. Since
+     * this method receives the event type and the listener object as
+     * parameters, it will unregister all <code>object</code>'s methods that are
+     * registered to listen to events of type <code>eventType</code> generated
+     * by this component.
+     *
+     * <p>
+     * For more information on the inheritable event mechanism see the
+     * {@link com.vaadin.event com.vaadin.event package documentation}.
+     * </p>
+     *
+     * @param eventType
+     *            the exact event type the <code>object</code> listens to.
+     * @param listener
+     *            the listener that has registered to listen to events of type
+     *            <code>eventType</code> with one or more methods.
+     * @deprecated use a {@link Registration} from {@link #addListener} to
+     *             remove a listener
+     * @since 8.12
+     */
+    @Deprecated
+    @Override
+    public void removeListener(Class<?> eventType,
+            SerializableEventListener listener) {
+        if (eventRouter != null) {
+            eventRouter.removeListener(eventType, listener);
+        }
+    }
+
     /**
      * Removes one registered listener method. The given method owned by the
      * given object will no longer be called when the specified events are
index f525c6aa4d4769a1cbad5e7818f1bd37b0ab546d..24b97f12a7b3270486cdd2613b11611358ffb0bf 100644 (file)
 
 package com.vaadin.server;
 
-import java.io.Serializable;
-import java.util.EventListener;
-
 import javax.portlet.RenderResponse;
 
+import com.vaadin.event.SerializableEventListener;
+
 /**
  * Event listener notified when the bootstrap HTML is about to be generated and
  * send to the client. The bootstrap HTML is first constructed as an in-memory
@@ -30,7 +29,7 @@ import javax.portlet.RenderResponse;
  * @author Vaadin Ltd
  * @since 7.0.0
  */
-public interface BootstrapListener extends EventListener, Serializable {
+public interface BootstrapListener extends SerializableEventListener {
     /**
      * Lets this listener make changes to the fragment that makes up the actual
      * Vaadin application. In a typical Servlet deployment, this is the contents
index 925df5912172edd4544147e6bf5354934a079365..0708a23000f2d702f976a12462d4890a359f196c 100644 (file)
@@ -30,6 +30,7 @@ import java.util.List;
 import com.vaadin.annotations.HtmlImport;
 import com.vaadin.annotations.StyleSheet;
 import com.vaadin.event.EventRouter;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.Registration;
 import com.vaadin.shared.ui.BorderStyle;
 import com.vaadin.shared.ui.ui.PageClientRpc;
@@ -54,7 +55,7 @@ public class Page implements Serializable {
      * @see #addBrowserWindowResizeListener(BrowserWindowResizeListener)
      */
     @FunctionalInterface
-    public interface BrowserWindowResizeListener extends Serializable {
+    public interface BrowserWindowResizeListener extends SerializableEventListener {
         /**
          * Invoked when the browser window containing a UI has been resized.
          *
@@ -259,7 +260,7 @@ public class Page implements Serializable {
      */
     @Deprecated
     @FunctionalInterface
-    public interface UriFragmentChangedListener extends Serializable {
+    public interface UriFragmentChangedListener extends SerializableEventListener {
         /**
          * Event handler method invoked when the URI fragment of the page
          * changes. Please note that the initial URI fragment has already been
@@ -286,7 +287,7 @@ public class Page implements Serializable {
      * @since 8.0
      */
     @FunctionalInterface
-    public interface PopStateListener extends Serializable {
+    public interface PopStateListener extends SerializableEventListener {
         /**
          * Event handler method invoked when the URI fragment of the page
          * changes. Please note that the initial URI fragment has already been
@@ -566,18 +567,18 @@ public class Page implements Serializable {
         this.state = state;
     }
 
-    private Registration addListener(Class<?> eventType, Object target,
+    private Registration addListener(Class<?> eventType, SerializableEventListener listener,
             Method method) {
         if (!hasEventRouter()) {
             eventRouter = new EventRouter();
         }
-        return eventRouter.addListener(eventType, target, method);
+        return eventRouter.addListener(eventType, listener, method);
     }
 
-    private void removeListener(Class<?> eventType, Object target,
+    private void removeListener(Class<?> eventType, SerializableEventListener listener,
             Method method) {
         if (hasEventRouter()) {
-            eventRouter.removeListener(eventType, target, method);
+            eventRouter.removeListener(eventType, listener, method);
         }
     }
 
index 8e98d73f3be54fb377977d220da16c5038ec61d9..3308cba1b4d29fbd917b8a6f365f4f9048d90226 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.vaadin.ui;
 
-import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.Collection;
 
@@ -24,6 +23,7 @@ import org.jsoup.nodes.Attributes;
 import org.jsoup.nodes.Element;
 
 import com.vaadin.event.Action;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.event.ShortcutAction;
 import com.vaadin.event.ShortcutAction.KeyCode;
 import com.vaadin.event.ShortcutAction.ModifierKey;
@@ -303,7 +303,7 @@ public class Button extends AbstractFocusable
      * @since 3.0
      */
     @FunctionalInterface
-    public interface ClickListener extends Serializable {
+    public interface ClickListener extends SerializableEventListener {
 
         public static final Method BUTTON_CLICK_METHOD = ReflectTools
                 .findMethod(ClickListener.class, "buttonClick",
index d4a4375dd9bf7b3c90fda3d1fbf42daff15cc167..6987a3e7a6a656601fd28309242cb8a48d0acfd7 100644 (file)
@@ -19,6 +19,7 @@ import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.Iterator;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.Registration;
 import com.vaadin.util.ReflectTools;
 
@@ -98,7 +99,7 @@ public interface HasComponents extends Component, Iterable<Component> {
      * Component attach listener interface.
      */
     @FunctionalInterface
-    public interface ComponentAttachListener extends Serializable {
+    public interface ComponentAttachListener extends SerializableEventListener {
 
         public static final Method attachMethod = ReflectTools.findMethod(
                 ComponentAttachListener.class, "componentAttachedToContainer",
@@ -117,7 +118,7 @@ public interface HasComponents extends Component, Iterable<Component> {
      * Component detach listener interface.
      */
     @FunctionalInterface
-    public interface ComponentDetachListener extends Serializable {
+    public interface ComponentDetachListener extends SerializableEventListener {
 
         public static final Method detachMethod = ReflectTools.findMethod(
                 ComponentDetachListener.class, "componentDetachedFromContainer",
index 2bb9fade6598a27a692a8b4c922719570cc7ea54..a914461ad958888738ef2f5eeaed043bd7bcc843 100644 (file)
@@ -18,12 +18,12 @@ package com.vaadin.ui;
 
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
-import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
 import java.util.Map;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.StreamResource;
 import com.vaadin.shared.ApplicationConstants;
 import com.vaadin.shared.Registration;
@@ -95,7 +95,7 @@ public class LoginForm extends AbstractSingleComponentContainer {
      * Listener triggered when a login occurs in a {@link LoginForm}.
      */
     @FunctionalInterface
-    public interface LoginListener extends Serializable {
+    public interface LoginListener extends SerializableEventListener {
         /**
          * Event method invoked when the login button is pressed in a login
          * form.
index 2204ea0b608ba2308ddae2e1cf3c72db456683e9..7832953c52a779250aa12f60e196bcffb0315db1 100644 (file)
 
 package com.vaadin.ui;
 
-import java.io.Serializable;
 import java.lang.reflect.Method;
 
 import com.vaadin.event.ConnectorEvent;
 import com.vaadin.event.HasUserOriginated;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.AbstractExtension;
 import com.vaadin.server.Page;
 import com.vaadin.server.Resource;
@@ -572,7 +572,7 @@ public class Notification extends AbstractExtension {
      * @since 8.2
      */
     @FunctionalInterface
-    public interface CloseListener extends Serializable {
+    public interface CloseListener extends SerializableEventListener {
         /**
          * Use {@link CloseEvent#getNotification()} to get a reference to the
          * {@link Notification} that was closed.
index dabcab7803edc7cc76526e7087706b165b68e9ea..72a5cd07c40152bdeeca7b2cc2efe35bd8d6b1f5 100644 (file)
@@ -24,6 +24,7 @@ import org.jsoup.nodes.Element;
 import org.jsoup.nodes.Node;
 import org.jsoup.parser.Tag;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.shared.Registration;
 import com.vaadin.shared.ui.popupview.PopupViewServerRpc;
 import com.vaadin.shared.ui.popupview.PopupViewState;
@@ -400,7 +401,7 @@ public class PopupView extends AbstractComponent implements HasComponents {
      *
      */
     @FunctionalInterface
-    public interface PopupVisibilityListener extends Serializable {
+    public interface PopupVisibilityListener extends SerializableEventListener {
         /**
          * Pass to {@link PopupView.PopupVisibilityEvent} to start listening for
          * popup visibility changes.
index 75b08bf5dcdbb5d1d9c2ee912dfa55900beb8b80..e2ef441c714e060bf037e131938112a3250d64b1 100644 (file)
@@ -24,7 +24,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 
 import org.jsoup.nodes.Attributes;
 import org.jsoup.nodes.Element;
@@ -37,6 +36,7 @@ import com.vaadin.event.FieldEvents.FocusEvent;
 import com.vaadin.event.FieldEvents.FocusListener;
 import com.vaadin.event.FieldEvents.FocusNotifier;
 import com.vaadin.event.HasUserOriginated;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.ErrorMessage;
 import com.vaadin.server.KeyMapper;
 import com.vaadin.server.Resource;
@@ -851,7 +851,7 @@ public class TabSheet extends AbstractComponentContainer
      * @since 3.0
      */
     @FunctionalInterface
-    public interface SelectedTabChangeListener extends Serializable {
+    public interface SelectedTabChangeListener extends SerializableEventListener {
 
         /**
          * Selected (shown) tab in tab sheet has has been changed.
index c47e5f14517669a16ee9d13e18e79ca35421893a..ca391a69c33031961db14cafb9276e0b750fd16f 100644 (file)
@@ -23,6 +23,7 @@ import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Objects;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.NoInputStreamException;
 import com.vaadin.server.NoOutputStreamException;
 import com.vaadin.server.PaintException;
@@ -535,7 +536,7 @@ public class Upload extends AbstractComponent
      * @since 5.0
      */
     @FunctionalInterface
-    public interface StartedListener extends Serializable {
+    public interface StartedListener extends SerializableEventListener {
 
         /**
          * Upload has started.
@@ -553,7 +554,7 @@ public class Upload extends AbstractComponent
      * @since 3.0
      */
     @FunctionalInterface
-    public interface FinishedListener extends Serializable {
+    public interface FinishedListener extends SerializableEventListener {
 
         /**
          * Upload has finished.
@@ -571,7 +572,7 @@ public class Upload extends AbstractComponent
      * @since 3.0
      */
     @FunctionalInterface
-    public interface FailedListener extends Serializable {
+    public interface FailedListener extends SerializableEventListener {
 
         /**
          * Upload has finished unsuccessfully.
@@ -589,7 +590,7 @@ public class Upload extends AbstractComponent
      * @since 3.0
      */
     @FunctionalInterface
-    public interface SucceededListener extends Serializable {
+    public interface SucceededListener extends SerializableEventListener {
 
         /**
          * Upload successful.
@@ -606,7 +607,7 @@ public class Upload extends AbstractComponent
      * @since 7.2
      */
     @FunctionalInterface
-    public interface ChangeListener extends Serializable {
+    public interface ChangeListener extends SerializableEventListener {
 
         Method FILENAME_CHANGED = ReflectTools.findMethod(ChangeListener.class,
                 "filenameChanged", ChangeEvent.class);
index f53659bdd3a73c2767df31f4a508417c1ed70cf9..edfc85a4a45bbf847a9bc5d2a7e9466ac4cbb36c 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.vaadin.ui;
 
-import java.io.Serializable;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -36,6 +35,7 @@ import com.vaadin.event.FieldEvents.FocusEvent;
 import com.vaadin.event.FieldEvents.FocusListener;
 import com.vaadin.event.FieldEvents.FocusNotifier;
 import com.vaadin.event.MouseEvents.ClickEvent;
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.event.ShortcutAction;
 import com.vaadin.event.ShortcutAction.KeyCode;
 import com.vaadin.event.ShortcutAction.ModifierKey;
@@ -496,7 +496,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
      * </p>
      */
     @FunctionalInterface
-    public interface CloseListener extends Serializable {
+    public interface CloseListener extends SerializableEventListener {
         /**
          * Called when the user closes a window. Use
          * {@link CloseEvent#getWindow()} to get a reference to the
@@ -599,7 +599,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
      * {@link WindowMode#MAXIMIZED}) or restored ({@link WindowMode#NORMAL} ).
      */
     @FunctionalInterface
-    public interface WindowModeChangeListener extends Serializable {
+    public interface WindowModeChangeListener extends SerializableEventListener {
 
         public static final Method windowModeChangeMethod = ReflectTools
                 .findMethod(WindowModeChangeListener.class, "windowModeChanged",
@@ -699,7 +699,7 @@ public class Window extends Panel implements FocusNotifier, BlurNotifier {
      * @see com.vaadin.ui.Window.ResizeEvent
      */
     @FunctionalInterface
-    public interface ResizeListener extends Serializable {
+    public interface ResizeListener extends SerializableEventListener {
         public void windowResized(ResizeEvent e);
     }
 
index e1215059844fdda1d81f23685dd393bdc0858638..e0ee1b8826b017a46abc35607710966e20139af5 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -26,7 +25,7 @@ import com.vaadin.ui.Grid;
  * @since 8.0
  */
 @FunctionalInterface
-public interface ColumnReorderListener extends Serializable {
+public interface ColumnReorderListener extends SerializableEventListener {
 
     /**
      * Called when the columns of the grid have been reordered.
index fa73eb27d9569014371a7eadb676c8a72e7e64ea..c05c5dcc2a6150006efc1999b4c79cc1767becab 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -26,7 +25,7 @@ import com.vaadin.ui.Grid;
  * @since 8.0
  */
 @FunctionalInterface
-public interface ColumnResizeListener extends Serializable {
+public interface ColumnResizeListener extends SerializableEventListener {
 
     /**
      * Called when the columns of the grid have been resized.
index fc7333b2bad781e6b7555d5f66af58b8b769b930..ba54cf76cfce186a010f0f7b208cd75e2f73e4a1 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -26,7 +25,7 @@ import com.vaadin.ui.Grid;
  * @since 8.0
  */
 @FunctionalInterface
-public interface ColumnVisibilityChangeListener extends Serializable {
+public interface ColumnVisibilityChangeListener extends SerializableEventListener {
 
     /**
      * Called when a column has become hidden or unhidden.
index d29a8d18a7fe80ad38f6424ec1a550660ffcde70..6588f52f5e9a226d37ee5972933d002ece5afd3c 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -32,7 +31,7 @@ import com.vaadin.ui.Grid;
  *            the bean type
  */
 @FunctionalInterface
-public interface EditorCancelListener<T> extends Serializable {
+public interface EditorCancelListener<T> extends SerializableEventListener {
 
     /**
      * Called when the editor is cancelled.
index cd9af878a3522137ac6ddd78f6dc0bc6eb3b956a..ca888ca77b6c6473f88f51690f30257979f0e05a 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -32,7 +31,7 @@ import com.vaadin.ui.Grid;
  * @see Editor#addOpenListener(EditorOpenListener)
  */
 @FunctionalInterface
-public interface EditorOpenListener<T> extends Serializable {
+public interface EditorOpenListener<T> extends SerializableEventListener {
 
     /**
      * Called when the editor is opened.
index 3e22a11aa7d764402d9a39cc1ead9b083bbaecfc..a267c01b71bf095f58fff20be746819d354429aa 100644 (file)
@@ -15,8 +15,7 @@
  */
 package com.vaadin.ui.components.grid;
 
-import java.io.Serializable;
-
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.ui.Grid;
 
 /**
@@ -29,7 +28,7 @@ import com.vaadin.ui.Grid;
  * @see Editor#addSaveListener(EditorSaveListener)
  */
 @FunctionalInterface
-public interface EditorSaveListener<T> extends Serializable {
+public interface EditorSaveListener<T> extends SerializableEventListener {
 
     /**
      * Called when the editor is saved.
index 6878fc1bc6e208a43fef6b88b1022592662be0d5..9eaec04627e1ef1fdbbaddcc6929f77286d0ae8a 100644 (file)
@@ -3,6 +3,7 @@ package com.vaadin.tests.minitutorials.v7a3;
 import java.lang.reflect.Method;
 import java.util.EventObject;
 
+import com.vaadin.event.SerializableEventListener;
 import com.vaadin.server.AbstractExtension;
 import com.vaadin.tests.widgetset.client.minitutorials.v7a3.RefresherRpc;
 import com.vaadin.tests.widgetset.client.minitutorials.v7a3.RefresherState;
@@ -10,7 +11,7 @@ import com.vaadin.ui.UI;
 import com.vaadin.util.ReflectTools;
 
 public class Refresher extends AbstractExtension {
-    public interface RefreshListener {
+    public interface RefreshListener extends SerializableEventListener {
         static Method METHOD = ReflectTools.findMethod(RefreshListener.class,
                 "refresh", RefreshEvent.class);