Skip to content

Commit 5ae0625

Browse files
committed
Add API to add and obtain typed listeners to/from Widgets
1 parent 7479681 commit 5ae0625

File tree

5 files changed

+331
-41
lines changed

5 files changed

+331
-41
lines changed

bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/widgets/Widget.java

Lines changed: 106 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2017 IBM Corporation and others.
2+
* Copyright (c) 2000, 2024 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,6 +13,9 @@
1313
*******************************************************************************/
1414
package org.eclipse.swt.widgets;
1515

16+
import java.util.*;
17+
import java.util.stream.*;
18+
1619
import org.eclipse.swt.*;
1720
import org.eclipse.swt.events.*;
1821
import org.eclipse.swt.internal.*;
@@ -439,11 +442,11 @@ boolean resignFirstResponder (long id, long sel) {
439442
}
440443

441444
/**
442-
* Adds the listener to the collection of listeners who will
445+
* Adds the listener to the collection of {@link Listener listeners} who will
443446
* be notified when an event of the given type occurs. When the
444447
* event does occur in the widget, the listener is notified by
445448
* sending it the <code>handleEvent()</code> message. The event
446-
* type is one of the event constants defined in class <code>SWT</code>.
449+
* type is one of the event constants defined in class {@link SWTError}.
447450
*
448451
* @param eventType the type of event to listen for
449452
* @param listener the listener which should be notified when the event occurs
@@ -456,8 +459,6 @@ boolean resignFirstResponder (long id, long sel) {
456459
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
457460
* </ul>
458461
*
459-
* @see Listener
460-
* @see SWT
461462
* @see #getListeners(int)
462463
* @see #removeListener(int, Listener)
463464
* @see #notifyListeners
@@ -468,6 +469,43 @@ public void addListener (int eventType, Listener listener) {
468469
_addListener (eventType, listener);
469470
}
470471

472+
/**
473+
* Adds the {@link EventListener typed listener} to the collection of listeners
474+
* who will be notified when an event of the given types occurs.
475+
* When the event does occur in the widget, the listener is notified
476+
* by calling the type's handling methods.
477+
* The event type is one of the event constants defined in class {@link SWT}
478+
* and must correspond to the listeners type.
479+
* If for example a {@link SelectionListener} is passed the {@code eventTypes}
480+
* can be {@link SWT#Selection} or {@link SWT#DefaultSelection}.
481+
*
482+
* @param listener the listener which should be notified when the event occurs
483+
* @param eventTypes the types of event to listen for
484+
*
485+
* @exception IllegalArgumentException <ul>
486+
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
487+
* </ul>
488+
* @exception SWTException <ul>
489+
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
490+
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
491+
* </ul>
492+
*
493+
* @see #getTypedListeners(int, Class)
494+
* @see #removeTypedListener(int, EventListener)
495+
* @see #notifyListeners
496+
* @since 3.126
497+
*/
498+
protected void addTypedListener (EventListener listener, int... eventTypes) {
499+
checkWidget();
500+
if (listener == null) {
501+
SWT.error(SWT.ERROR_NULL_ARGUMENT);
502+
}
503+
TypedListener typedListener = new TypedListener(listener);
504+
for (int eventType : eventTypes) {
505+
_addListener(eventType, typedListener);
506+
}
507+
}
508+
471509
void _addListener (int eventType, Listener listener) {
472510
if (eventTable == null) eventTable = new EventTable ();
473511
eventTable.hook (eventType, listener);
@@ -948,9 +986,9 @@ boolean getDrawing () {
948986
}
949987

950988
/**
951-
* Returns an array of listeners who will be notified when an event
989+
* Returns an array of {@link Listener listeners} who will be notified when an event
952990
* of the given type occurs. The event type is one of the event constants
953-
* defined in class <code>SWT</code>.
991+
* defined in class {@link SWT}.
954992
*
955993
* @param eventType the type of event to listen for
956994
* @return an array of listeners that will be notified when the event occurs
@@ -960,8 +998,6 @@ boolean getDrawing () {
960998
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
961999
* </ul>
9621000
*
963-
* @see Listener
964-
* @see SWT
9651001
* @see #addListener(int, Listener)
9661002
* @see #removeListener(int, Listener)
9671003
* @see #notifyListeners
@@ -974,6 +1010,33 @@ public Listener[] getListeners (int eventType) {
9741010
return eventTable.getListeners(eventType);
9751011
}
9761012

1013+
/**
1014+
* Returns the typed listeners who will be notified when an event of the given type occurs.
1015+
* The event type is one of the event constants defined in class {@link SWT}
1016+
* and the specified listener-type must correspond to that event.
1017+
* If for example the {@code eventType} is {@link SWT#Selection},
1018+
* the listeners type should be {@link SelectionListener}.
1019+
*
1020+
* @param eventType the type of event to listen for
1021+
* @return a stream of typed listeners that will be notified when the event occurs
1022+
*
1023+
* @exception SWTException <ul>
1024+
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1025+
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1026+
* </ul>
1027+
*
1028+
* @see #addTypedListener(EventListener, int...)
1029+
* @see #removeTypedListener(int, EventListener)
1030+
* @see #notifyListeners
1031+
*
1032+
* @since 3.126
1033+
*/
1034+
public <L extends EventListener> Stream<L> getTypedListeners (int eventType, Class<L> listenerType) {
1035+
return Arrays.stream(getListeners(eventType)) //
1036+
.filter(TypedListener.class::isInstance).map(l -> ((TypedListener) l).eventListener)
1037+
.filter(listenerType::isInstance).map(listenerType::cast);
1038+
}
1039+
9771040
String getName () {
9781041
String string = getClass ().getName ();
9791042
int index = string.lastIndexOf ('.');
@@ -1463,11 +1526,42 @@ public void removeListener (int eventType, Listener listener) {
14631526
* @noreference This method is not intended to be referenced by clients.
14641527
* @nooverride This method is not intended to be re-implemented or extended by clients.
14651528
*/
1466-
protected void removeListener (int eventType, SWTEventListener handler) {
1529+
protected void removeListener (int eventType, SWTEventListener listener) {
1530+
removeTypedListener(eventType, listener);
1531+
}
1532+
1533+
/**
1534+
* Removes the listener from the collection of listeners who will
1535+
* be notified when an event of the given type occurs.
1536+
* <p>
1537+
* <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT
1538+
* public API. It is marked public only so that it can be shared
1539+
* within the packages provided by SWT. It should never be
1540+
* referenced from application code.
1541+
* </p>
1542+
*
1543+
* @param eventType the type of event to listen for
1544+
* @param listener the listener which should no longer be notified
1545+
*
1546+
* @exception IllegalArgumentException <ul>
1547+
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1548+
* </ul>
1549+
* @exception SWTException <ul>
1550+
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1551+
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1552+
* </ul>
1553+
*
1554+
* @see Listener
1555+
* @see #addListener
1556+
*
1557+
* @noreference This method is not intended to be referenced by clients.
1558+
* @nooverride This method is not intended to be re-implemented or extended by clients.
1559+
*/
1560+
protected void removeTypedListener (int eventType, EventListener listener) {
14671561
checkWidget();
1468-
if (handler == null) error (SWT.ERROR_NULL_ARGUMENT);
1562+
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
14691563
if (eventTable == null) return;
1470-
eventTable.unhook (eventType, handler);
1564+
eventTable.unhook (eventType, listener);
14711565
}
14721566

14731567
/**

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/EventTable.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2011 IBM Corporation and others.
2+
* Copyright (c) 2000, 2024 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -14,6 +14,8 @@
1414
package org.eclipse.swt.widgets;
1515

1616

17+
import java.util.*;
18+
1719
import org.eclipse.swt.*;
1820
import org.eclipse.swt.internal.*;
1921

@@ -145,12 +147,12 @@ public void unhook (int eventType, Listener listener) {
145147
}
146148
}
147149

148-
public void unhook (int eventType, SWTEventListener listener) {
150+
public void unhook (int eventType, EventListener listener) {
149151
if (types == null) return;
150152
for (int i=0; i<types.length; i++) {
151153
if (types [i] == eventType) {
152154
if (listeners [i] instanceof TypedListener typedListener) {
153-
if (typedListener.getEventListener () == listener) {
155+
if (typedListener.eventListener == listener) {
154156
remove (i);
155157
return;
156158
}

bundles/org.eclipse.swt/Eclipse SWT/common/org/eclipse/swt/widgets/TypedListener.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
package org.eclipse.swt.widgets;
1515

1616

17-
import org.eclipse.swt.internal.SWTEventListener;
17+
import java.util.*;
18+
1819
import org.eclipse.swt.*;
1920
import org.eclipse.swt.events.*;
21+
import org.eclipse.swt.internal.*;
2022

2123
/**
2224
* Instances of this class are <em>internal SWT implementation</em>
@@ -40,7 +42,7 @@ public class TypedListener implements Listener {
4042
/**
4143
* The receiver's event listener
4244
*/
43-
protected SWTEventListener eventListener;
45+
protected EventListener eventListener;
4446

4547
/**
4648
* Constructs a new instance of this class for the given event listener.
@@ -59,6 +61,10 @@ public TypedListener (SWTEventListener listener) {
5961
eventListener = listener;
6062
}
6163

64+
TypedListener (EventListener listener) {
65+
eventListener = listener;
66+
}
67+
6268
/**
6369
* Returns the receiver's event listener.
6470
* <p>
@@ -73,7 +79,11 @@ public TypedListener (SWTEventListener listener) {
7379
* @noreference This method is not intended to be referenced by clients.
7480
*/
7581
public SWTEventListener getEventListener () {
76-
return eventListener;
82+
// At the moment all typed listeners implement SWTEventListener but that interface is intended to be removed in the future and then they will only implement EventListener.
83+
// This method should not be called for typed listeners listeners that only implement EventListener.
84+
// This is only relevant for custom typed listeners that implement EventListener directly before SWTEventListener is eventually removed.
85+
// But then the new Widget.getTypedListener() method can be used.
86+
return (SWTEventListener) eventListener;
7787
}
7888

7989
/**

0 commit comments

Comments
 (0)