I am using Eclipse 4.2 Juno, Java 1.6. I have two parts in my application. One part is registering the SelectionChangedListener:
#Inject
private ESelectionService selectionService;
#PostConstruct
public void init() {
TreeViewer bsTreeViewer = new TreeViewer(tabFolder, SWT.BORDER);
/* some other stuff */
// Event declaration
bsTreeViewer.addSelectionChangedListener(new SelectionChangedListener() {
#Override
public void selectionChanged(SelectionChangedEvent event) {
if( selectionService != null ) {
selectionService.setSelection(((IStructuredSelection)event.getSelection()).getFirstElement());
}
}
});
}
This Listener is called correctly. The first selected Element is of the right type, too.
I another part I am setting up the receiving end:
#Inject
public void setBS(#Named(IServiceConstants.ACTIVE_SELECTION) #Optional BS bs) {
if (bs == null) {
/* implementation not shown */
} else {
/* implementation not shown */
}
}
However, nothing is received on this end of the pipe. What am I doing wrong or how could I debug this?
The code above looks fine, but try to check the following issues:
check if the receiver object is created - if not, it won't receive an event
check if the receiver object is created by eclipse framework (for example if it is element of application model such as part, handler it is for sure created by the framework) - if not, the framework (selection service) does not know about the receiver object and cannot notify it
Related
The case is simple: I have several ajax components and I want to update them when some ajax action is
happened. It is easy when all of these components are in the same place and they can be reached one by another.
But if the page has a huge hierarchy this can be not so trivial and to solve this problem I would like to send some global event (which will contain an IPartialPageRequestHandler) and all these components should catch it and update himself.
How can I do this in wicket?
Actualy I see onEvent method in the component class and I can access IPartialPageRequestHandler inside of it:
public void onEvent(IEvent<?> event){
Object payload = event.getPayload();
if (payload instanceof IPartialPageRequestHandler) {
...
}
}
but how can I create the global event that should be catched by this method?
Create a custom event, for example:
public class CounterUpdate
{
private final AjaxRequestTarget target;
/**
* Constructor
*
* #param target
*/
public CounterUpdate(AjaxRequestTarget target)
{
this.target = target;
}
/** #return ajax request target */
public AjaxRequestTarget getTarget()
{
return target;
}
}
In your Ajax callback method broadcast it:
send(getPage(), Broadcast.BREADTH, new CounterUpdate(target));
In any Component/Behavior that is interested for this event do:
#Override
public void onEvent(IEvent<?> event)
{
super.onEvent(event);
// check if this is a counter update event and if so repaint self
if (event.getPayload() instanceof CounterUpdate)
{
CounterUpdate update = (CounterUpdate)event.getPayload();
update.getTarget().add(this);
}
}
you could notify the entire page or application 'page.send(...)' or 'application.send(...)'. Wicket already does it for every AJAX event to notify the entire page hierarchy. See the end of this paragraph from user guide:
https://ci.apache.org/projects/wicket/guide/8.x/single.html#_how_to_use_ajax_components_and_behaviors
I am creating eclipse RCP 4.x application. Application consist of multiple perspectives. I want to open default perspective programmatically depending on some condition. Below code is capable of loading perspective.
#Execute
public void execute(MApplication app, EPartService partService,
EModelService modelService) {
MPerspective element =
(MPerspective) modelService.find("com.sanyotechnologyindia.desktop.app.perspective.enduser", app);
// now switch perspective
partService.switchPerspective(element);
}
But I can not put this code in method which is annotated with #PostContextCreate.
Can you suggest any solution for this?
================
As per solution suggested by Greg, I tried following code in Application Lifecycle class.
#ProcessAdditions
void processAdditions(MApplication app, EPartService partService,
EModelService modelService){
MPerspective element =
(MPerspective) modelService.find("com.sanyotechnologyindia.desktop.app.perspective.usermanagement", app);
// now switch perspective
partService.switchPerspective(element);
}
Now I am getting following error at line partService.switchPerspective(element);
java.lang.IllegalStateException: Application does not have an active window
================Update:==================
Added org.eclipse.osgi.services plugin to dependencies.
#PostContextCreate
public void postContextContext(IEventBroker eventBroker)
{
eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE,
new AppStartupCompleteEventHandler());
}
private class AppStartupCompleteEventHandler implements EventHandler
{
#Inject private MApplication app;
#Inject private EPartService partService;
#Inject private EModelService modelService;
#Override
public void handleEvent(Event arg0) {
MPerspective element =
(MPerspective) modelService.find("com.sanyotechnologyindia.desktop.app.perspective.usermanagement", app);
partService.switchPerspective(element);
}
}
However now framework not able to inject MApplication,EPartService and EModelService in AppStartupCompleteEventHandler instance.
If you only want to do this in your life cycle class try putting it in a #ProcessAdditions method rather than #PostContextCreate. #ProcessAdditions runs later in the life cycle just before the model is rendered.
Update:
Even #PostAdditions is too early to do some UI operations. You need to wait for the application start complete event. You can subscribe to this event using the event broker in the #PostContextCreate method:
#PostContextCreate
public void postContextContext(IEventBroker eventBroker)
{
eventBroker.subscribe(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE,
new AppStartupCompleteEventHandler());
}
private class AppStartupCompleteEventHandler implements EventHandler
{
#Override
public void handleEvent(final Event event)
{
// TODO do UI operations here
}
}
EventHandler is org.osgi.service.event.EventHandler.
Update:
If you want to use injection in the event handler you must create the handler using `ContextInjectionFactory':
EventHandler handler = ContextInjectionFactory.make(AppStartupCompleteEventHandler.class, context);
where context is the IEclipseContext.
Note: You can't use this for a non-static inner class, instead use:
EventHandler handler = new AppStartupCompleteEventHandler();
ContextInjectionFactory.inject(handler, context);
This method does not support injection on the constructor.
I want to know that is it possible to send major Swing classes event/actionlisteners, Events, components via RMI.
Possible scenario: If one client press the button or move the slider every client's button or slider move etc same for other swing elements.
I am expecting the answer in the context of RMI and swing MVC architecture, i want to call the swing component's models e.g ButtonModel and want to send swing ActionEvent on wire and register PropertyChangeListener/PropertyChangeSupport as remote objects for getting updates at client site.
typical examples :
the server should call this method for each client, when ever some change occur in model
public void propertyChange(PropertyChangeEvent evt) {
for (AbstractViewPanel view: registeredViews) {
view.modelPropertyChange(evt);
}
}
in case of an event on one client, each client actionPerformed should be called from server:
#Override
public void actionPerformed(ActionEvent e) {
}
is it feasible? if not then why? where i could face the problems, i mean which classes are transferable (serialized) and which are not...
EDIT: here you see i m invoking Java Swing defaultbuttonmodel remotely, the only thing left when some of it's property or method change the other client's get updates, best would be following swing propertychangelistener if someone can just help me, realizing this, it would be great:
public class RemoteButtonModel extends UnicastRemoteObject implements Model {
private ButtonModel model = new DefaultButtonModel() ;
protected myModel() throws RemoteException {
super();
}
#Override
public void setEnabled(boolean b) throws RemoteException {
if (isEnabled())
model.setEnabled(false);
else{
model.setEnabled(true);
}
}
#Override
public boolean isEnabled() throws RemoteException {
return model.isEnabled();
}
}
I think it would be more efficient to send across something like a "scroll message" or "button pressed" message, utilizing the command pattern. This would allow different clients to act correctly with different implementations.
Edits:
the way I do it in my client/server applications (which is easily adapted to this peer-to-peer architecture you're doing) is with something like this (copy and pasted from my production code, mind you.)
abstract public class UserRequest implements Serializable {
public final String username;
private transient ServersideThread thread;
protected UserRequest(String username) {
this.username = username;
this.thread = null;
}
abstract public EngineMessage engineCallback(GenericEngine engine);
public void setThread(ServersideThread thread) {
if(this.thread == null) {
this.thread = thread;
return;
}
throw new IllegalStateException("Cannot set thread when already set:" + thread.getName());
}
public ServersideThread getThread() {
return this.thread;
}
}
So, with this approach, I would do something like...
public class SliderMoveNotification extends UserRequest {
// need some way to say what slider moved
public final int sliderId;
public final int slideDistance;
public SliderMoveNotification(String username) {
super(username);
sliderId = 0;
sliderDistance = 0;
throw new UnsupportedOperationException("Must supply a slider and a distance");
}
public SliderMoveNotification(String username, int sliderID, int slideDistance) {
super(username);
this.sliderId = sliderId;
this.slideDistance = slideDistance;
}
public EngineMessage engineCallback(GenericEngine engine) {
if(engine instanceof WindowEngine) {
WindowEngine manager = (WindowEngine)engine;
manager.slideWindow(sliderId,slideDistance);
// you wouldn't need engine messages like I do in my client/server
// relationship, but the idea stands.
}
}
}
The Javadoc for every Swing class says that it should not be serialized.
More probably you should be transmitting the associated Model classes.
And event listening via RMI is an anti-pattern. Too much traffic, too many points of failure.
Very typically I have a situation where a given object will need to have many listeners. For instance, I might have
class Elephant {
public void addListener( ElephantListener listener ) { ... }
}
but I'll have many such situations. That is, I'll also have a Tiger object that'll have TigerListeners. Now, TigerListeners and ElephantListeners are quite different:
interface TigerListener {
void listenForGrowl( Growl qrowl );
void listenForMeow( Meow meow );
}
while
interface ElephantListener {
void listenForStomp( String location, double intensity );
}
I find that I always have to keep re-implementing the broadcasting mechanism in each animal class, and the implementation is always the same. Is there a preferred pattern?
Instead of each Listener having specific methods for every event type you can send it, change the interface to accept a generic Event class. You can then subclass Event to specific subtypes if you need, or have it contain state such as double intensity.
TigerListener and ElephentListener then become
interface TigerListener {
void listen(Event event);
}
In fact, you can then further refactor this interface into a plain Listener:
interface Listener {
void listen(Event event);
}
Your Listener implementations can then contain the logic that they need for the specific events they care about
class TigerListener implements Listener {
#Overrides
void listen(Event event) {
if (event instanceof GrowlEvent) {
//handle growl...
}
else if (event instance of MeowEvent) {
//handle meow
}
//we don't care about any other types of Events
}
}
class ElephentListener {
#Overrides
void listen(Event event) {
if (event instanceof StompEvent) {
StompEvent stomp = (StompEvent) event;
if ("north".equals(stomp.getLocation()) && stomp.getDistance() > 10) {
...
}
}
}
}
The key relationship between the subscriber and the publisher is that the publisher can send events to the subscribers, it isn't necessarily that it can send it certain types of events - this type of refactoring pushes that logic from the interface down into the specific implementations.
This is a more general answer for people who come here just wanting to make a listener. I am summarizing Creating Custom Listeners from CodePath. Read that article if you need more explanation.
Here are the steps.
1. Define an Interface
This is in the child class that needs to communicate with some unknown parent.
public class MyClass {
// interface
public interface MyClassListener {
// add whatever methods you need here
public void onSomeEvent(String title);
}
}
2. Create a Listener Setter
Add a private listener member variable and a public setter method to the child class.
public class MyClass {
// add a private listener variable
private MyClassListener mListener = null;
// provide a way for another class to set the listener
public void setMyClassListener(MyClassListener listener) {
this.mListener = listener;
}
// interface from Step 1
public interface MyClassListener {
public void onSomeEvent(String title);
}
}
3. Trigger Listener Events
The child object can now call methods on the listener interface. Be sure to check for null because there might not be anyone listening. (That is, the parent class might not have called the setter method for our listener.)
public class MyClass {
public void someMethod() {
// ...
// use the listener in your code to fire some event
if (mListener != null)
mListener.onSomeEvent("hello");
}
// items from Steps 1 and 2
private MyClassListener mListener = null;
public void setMyClassListener(MyClassListener listener) {
this.mListener = listener;
}
public interface MyClassListener {
public void onSomeEvent(String myString);
}
}
4. Implement the Listener Callbacks in the Parent
The parent can now use the listener that we set up in the child class.
Example 1
public class MyParentClass {
private void someMethod() {
MyClass object = new MyClass();
object.setMyClassListener(new MyClass.MyClassListener() {
#Override
public void onSomeEvent(String myString) {
// handle event
}
});
}
}
Example 2
public class MyParentClass implements MyClass.MyClassListener {
public MyParentClass() {
MyClass object = new MyClass();
object.setMyClassListener(this);
}
#Override
public void onSomeEvent(String myString) {
// handle event
}
}
I think you're doing it correct, since your interfaces have semantic value and express what they are listening to (e.g. growls and meows instead of stomps). With a generic approach, you may be able to reuse the broadcasting code, but you may lose the readability.
For example, there is the java.beans.PropertyChangeSupport which is a utility for implementing Oberservers listening for value changes. It does the broadcasting, but you still need to implement the method in your domain class and delegate to the PropertyChangeSupport object. The callback methods are meaningless by themselves, and the events broadcasted are String-based:
public interface PropertyChangeListener extends java.util.EventListener {
void propertyChange(PropertyChangeEvent evt);
}
Another one is java.util.Observable which provides the broadcasting mechanism, but it's also not the best thing imho.
I like ElephantListener.onStomp()
A different options is the Whiteboard Pattern. This disconnects the publisher and subscriber from each other, and neither will contain any broadcasting code. They both simply use a messaging mechanism for pub/sub and neither has any direct connection to the other.
This is a common model for messaging in an OSGi platform.
I created a Signals library just for this purpose. To remove the boiler code involved in "re-implementing the broadcasting mechanism."
A Signal is an object created automatically from an interface. It has methods for adding listeners and dispatching/broadcasting events.
It looks like this:
interface Chat{
void onNewMessage(String s);
}
class Foo{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar(){
chatSignal.addListener( s-> Log.d("chat", s) ); // logs all the messaged to Logcat
}
}
class Foo2{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar2(){
chatSignal.dispatcher.onNewMessage("Hello from Foo2"); // dispatches "Hello from Foo2" message to all the listeners
}
}
In this example, Foo2 is the broadcaster of new messages over the Chat interface. Foo then listen to those and log it to logcat.
Note that there are no limitations on what interfaces you can use
You also have some sugar API for registering for only the first broadcast and unregistering from all the signals at once(Via the SignalsHelper)
Try the java kiss library and you will get this done faster and more correctly.
import static kiss.API.*;
class Elephant {
void onReceiveStomp(Stomp stomp) { ... }
}
class Tiger {
void onReceiveMeow(Meow meow) { ... }
void onReceiveGrowl(Growl growl) { ... }
}
class TigerMeowGenerator extends Generator<Meow> {
// to add listeners, you get:
// addListener(Object tiger); // anything with onReceiveMeow(Meow m);
// addListener(meow->actions()); // any lambda
// to send meow's to all listeners, use
// send(meow)
}
The generator is thread-safe and efficient (writing correct generators is the hardest part). It is an implementation of the ideas in
Java Dev. Journal - Skilled Listening in Java (local copy)
While simple, interface-driven event notification frameworks in Java have been around since pre-Cambrian times (e.g. java.beans.PropertyChangeSupport), it is becoming increasingly popular for frameworks to use annotation-driven event notification instead.
For an example, see JBossCache 2.2. The listener class has its listener methods annotated, rather than conforming to a rigid interface. This is rather easier to program to, and easier to read, since you don't have to write empty implementations of listener callbacks that you're not interested in (and yes, I know about listener adapter superclasses).
Here's a sample from the JBossCache docs:
#CacheListener
public class MyListener {
#CacheStarted
#CacheStopped
public void cacheStartStopEvent(Event e) {
switch (e.getType()) {
case Event.Type.CACHE_STARTED:
System.out.println("Cache has started");
break;
case Event.Type.CACHE_STOPPED:
System.out.println("Cache has stopped");
break;
}
}
#NodeCreated
#NodeRemoved
#NodeVisited
#NodeModified
#NodeMoved
public void logNodeEvent(NodeEvent ne) {
log("An event on node " + ne.getFqn() + " has occured");
}
}
The problem with this, is that it's very much more of an involved process writing the framework to support this sort of thing, due to the annotation-reflection nature of it.
So, before I charge off down the road of writing a generic framework, I was hoping someone had done it already. Has anyone come across such a thing?
You can already do this today with EventBus.
Following example is from EventBus Getting Started guide. Statusbar that updates based on published events, and no need to register statusbar control/widget as listener of publisher(s). Without EventBus, statusbar will need to be added as listener to many classes. Statusbar can also be created and destroyed at any time.
public StatusBar extends JLabel {
public StatusBar() {
AnnotationProcessor.process(this);
}
#EventSubscriber(eventClass=StatusEvent.class)
public void updateStatus(StatusEvent statusEvent) {
this.setText(statusEvent.getStatusText();
}
}
A similar project is ELF (Event Listener Framework) but it seems to be less mature.
I'm currently researching about event notification frameworks on Publish-Subscribe Event Driven Programming | Kev's Spring vs Java EE Dev and the followup articles.
I've made http://neoevents.googlecode.com to handle this kind of annotation based event handler.
#actionPerformed
private void onClick() {
//do something
}
protected void initComponents() {
JButton button = new JButton("Click me!!!");
button.addActionListener(new ActionListener(this) );
}
It looks as simple as I was expecting it to be. Annotations are available for every single listener in J2SE.
Don't mistake complicated for clever. It seems to me that this would be:
A nightmare to debug
Difficult to follow (from a maintenance perspective, or someone attempting to change something 6 months down the line)
Full of if (event instanceof NodeCreatedEvent) like code. Why this is better than subclassing an adapter I have no idea!
The main problem I see here are the method parameters, which restrict which methods can actually be used for which events, and there's no compile-time help for that.
This is what makes interfaces attractive to me for observer pattern implementations like the Java event model. Tools like eclipse can autogen method stubs so you can't get the signatures wrong. In your example, it's very easy to use the wrong parameter type and never know it until an event occurs (which might be an error case several months down the line)
One thing you might try are my annotations & processor for implementing observers and null object implementations. Suppose you have
package a.b.c;
public interface SomeListener {
void fee();
void fie();
void fo();
void fum();
}
and wanted to create a listener instance. You could write
package x.y.z;
import a.b.c.SomeListener;
import com.javadude.annotation.Bean;
import com.javadude.annotation.NullObject;
#Bean(nullObjectImplementations = {#NullObject(type = SomeListener.class) })
public class Foo extends FooGen implements SomeListener {
#Override
public void fie() {
// whatever code you need here
}
}
To create a source for these events, you can write
package a.b.c;
import com.javadude.annotation.Bean;
import com.javadude.annotation.Observer;
#Bean(observers = {#Observer(type = SomeListener.class)})
public class Source extends SourceGen {
// SourceGen will have add/remove listener and fire methods
// for each method in SomeListener
}
See http://code.google.com/p/javadude/wiki/Annotations if you're interested. Might give you some other ideas as well.
Google Guava v11 has added an EventBus component that uses this style. They also explain why they decided to use annotations rather than interfaces.
I've been thinking about a generic annotation-driven event framework as well. I like the benefits provided by static typing, but the current interface-driven event model is painful to use (ugly code). Would it be possible to use a custom annotation processor to do some compile-time checking? That might help add some of the missing "safety" that we've all grown used to.
A lot of the error checking can also be done at the time that the listeners are "registered" with the event producers. Thus, the application would fail early (when the listeners are registered), possibly even at at startup-time.
Here's an example of what the generic framework I've been toying with might look like:
public class ExampleProducer {
private EventSupport<ActionEvent> eventSupport;
public ExampleProducer() {
eventSupport = new EventSupport<ActionEvent>(this);
}
#AddListenersFor(ActionEvent.class)
public void addActionListener(Object listener)
{
eventSupport.addListener(listener);
}
#RemoveListenersFor(ActionEvent.class)
public void removeActionListener(Object listener)
{
eventSupport.removeListener(listener);
}
public void buttonClicked() {
eventSupport.fire(new ActionEvent(this,
ActionEvent.ACTION_PERFORMED, "Click"));
}
}
The producer uses EventSupport, which uses reflection to invoke the events. As mentioned before, EventSupport could preform some initial checks when the events listeners are registered.
public class ExampleListener
{
private ExampleProducer submitButton;
public ExampleListener()
{
submitButton = new ExampleProducer();
EventSupport.autoRegisterEvents(this);
}
#HandlesEventFor("submitButton")
public void handleSubmitButtonClick(ActionEvent event)
{
//...some code to handle the event here
}
}
Here, EventSupport has a static method that uses reflection to auto-register the listener with the event producer. This eliminates the need to manually register with the event source. A custom annotation processor could be used to validate that the #HandlesEventFor annotation refers to an actual field of the ExampleListener. The annotation processor could do other checks as well, such as ensuring that the event handler method signature matches up with one of the registration methods on the ExampleProducer (basically, the same check that could be performed at registration-time).
What do you think? Is this worth putting some time into fully developing?
Here's a similar project called SJES.
public class SomeController {
private Calculator c1 = new Calculator();
private Calculator c2 = new Calculator();
public SomeController() {
c1.registerReceiver(this);
c2.registerReceiver(this);
c1.add(10, 10);
c2.add(20, 20);
}
#EventReceiver(handleFor="c1")
public void onResultC1(Calculator.Event e) {
System.out.println("Calculator 1 got: " + e.result);
}
#EventReceiver(handleFor="c2")
public void onResultC2(Calculator.Event e) {
System.out.println("Calculator 2 got: " + e.result);
}
#EventReceiver
public void onResultAll(Calculator.Event e) {
System.out.println("Calculator got: " + e.result);
}
}
public class Calculator {
private EventHelper eventHelper = new EventHelper(this);
public class Event {
long result;
public Event(long result) {
this.result = result;
}
}
public class AddEvent extends Event {
public AddEvent(long result) {
super(result);
}
}
public class SubEvent extends Event {
public SubEvent(long result) {
super(result);
}
}
public void unregisterReceiver(Object o) {
eventHelper.unregisterReceiver(o);
}
public void registerReceiver(Object o) {
eventHelper.registerReceiver(o);
}
public void add(long a, long b) {
eventHelper.fireEvent(new AddEvent(a + b));
}
public void sub(long a, long b) {
eventHelper.fireEvent(new SubEvent(a - b));
}
public void pass(long a) {
eventHelper.fireEvent(new Event(a));
}
}
I think this is very easy to use.
You can also check out MBassador It is annotation driven, very light-weight and uses weak references (thus easy to integrate in environments where objects lifecycle management is done by a framework like spring or guice or somethign).
It provides an object filtering mechanism (thus you could subscribe to NodeEvent and attach some filters to restrict message handling to a set of specific types only).
You can also define your own annotations to have customized declaration of your handlers.
And it's very fast and resource efficient. Check out this benchmark showing a performance graph for different scenarios using Guava or mbassador.