Swing - replacement for Qt signal/slots - java

In Qt GUIs it is very convenient use signals & slots - it decouple events passing. When I create some widget that throw signal, I don't have to know in advance who can get it, and later with connect I specify connections.
What is parallel in Java/Swing? Can you point to good resources on this issue?

If none of the existing EventListener implementations meet your requirements, you can create your own custom event. Every JComponent contains a field of type EventListenerList. You can use the approach outlined in the EventListenerList API to enable your custom JComponent subclass to fire your custom event.
Regarding the signal/slot mechanism, Swing has several ways to implement the observer pattern, outlined here.

This Event Listener tutorial goes through the basics of handling events with listeners.
Connecting your slot for a signal is analogous to adding your EventListener to an event-producing object.

Related

Event Bus equivalent in iOS

Heard about java 'publish-subscribe' style communication between components without requiring the components to explicitly be aware of each other, which is Event bus.It seems that using event bus we can communicate between different classes very easily with less coding needed.I know that NSNotifications in iOS also do this. NSNotification is not a replacement here.Please let me know apart form delegation pattern what is a good solution in iOS which is a good replacement for EventBus for communication between classes.?
With Swift you can use SwiftEventBus. It's just a nice wrapper around NSNotificationCenter and DispatchQueue.
Register to an event:
SwiftEventBus.onMainThread(target, name: "someEventName") { result in
// UI thread
// Do something when the event occurr
}
Trigger an event:
SwiftEventBus.post("someEventName")
And if you need to customize it, the source code is short, clear and easy to understand.
I think you can use NSNotificationCenter for this, I read your comment about it is one-to-many and it's true by default but you can specify from which object do you want to receive messages like this:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(someSelector:)
name:#"MyPersonalNotification"
object:someOtherObject];
Here you will receive the MyPersonalNotification in someSelector: only when someOtherObject post it. This made the communication one-to-one.
Also you can use the Key-Value Observing API but I personally found it somewhat uncomfortable.
Have a look at tolo.
The functionality is somewhat similar to an event bus and it has one big advantage over NSNotification as you don't have to unregister when deallocating (like in iOS9).

What exactly is the difference between an app specific event and a GWT event and when is one supposed to be used over the other?

While consulting the javadocs for GwtEvent class this text snippet got me confused:
There is no need for an application's custom event types to extend
GwtEvent. Prefer Event instead.
Can someone please give a concrete situation example where Event is preferred to the gwtevent class?
Should ClearEvent ( defined here : http://alextretyakov.blogspot.ro/2011/11/gwt-event-bus-basics.html ) extend GwtEvent class or should it directly extend Event class?
GwtEvent extends Event. It just seems that the GWT team need some functionalities for most of its events. But you probably don't need those.
In our application most events are consumed directly. So we don't need to have those isLive(), kill(), revive() methods. I guess it's the same for most people.
IMO such methods are required when a chain of listeners can catch the event and forward it to each other. You would want to mark the event as "processed" to avoid it being consumed when the processing is over.
The code in the post you provided is not using those methods. So the answer is: the author didn't need to extends GWTEvent. Event will work just fine.

Is this a proper implementation of MVC in Swing?

I have read about MVC but am having doubts on how to implement the concept in Java with Swing. Here's what I'm going for:
The model:
ListOfThings contains a Collection of Thing objects.
The controller:
Controller instanciates ListOfThings and populates it with a "add" method (internally creates a new Thing and adds it to the Collection)
The view:
A Swing interface with a ListOfThingsPanel which will contain ThingPanel components to represent the model. Both extend JPanel. ThingPanel contains various components meant to display the data of the Thing it's linked to.
It also has a button which adds a new (empty) thing to the list.
The click event calls the Controller's addThing() method which asks ListOfThings to add a new Thing to its list. ListOfThings has an event/listener system and ListOfThingsPanel listens to it to know when it should refresh the view.
Am I properly following the MVC concept by doing it like this?
Update:
I'm still learning Java but I have coding experience and would prefer to learn the theory and attempt it by my own means before using premade frameworks. While I'm aware Swing implements the MVC pattern, I have read it does it in a specific way (View and Controller combined) which might not be the best and not applicable in other circumstances. I'm a bit wary until I can make sure "Swing MVC" is not different from "MVC", or that the differences won't impact my understanding of the underlying ideas.
One thing of import to me is to learn to really separate the model from the view to allow me to ultimately create various views of various types (Swing but also console or update to JavaFX for example) This is why I'd like to avoid anything Swing specific outside of the view part itself.
While the Swing framework already implements a form of MVC (explicit models; JXyz & UI classes = controller & view), this strict separation is rarely used on application level and looks rather weird.
To start I suggest to follow the following design:
implement the client-side business logic with POJOs
wrap the POJOs with custom Swing models where needed (ListModel, TableModel)
Use a GUI builder to design the GUI
Use the Mediator pattern to listen for events (a custom subclass of JPanel listens for events of its children and updates other children or fires own custom events if needed)
If you want to go a step further, use a RCP such as the NetBeans Platform (very recommended).
Edit:
And here is the article explaining MVC in Swing:
http://www.oracle.com/technetwork/java/architecture-142923.html

Is there an standard class for Events in Java?

I wrote a Listener. Now I want to notify it, when a change occurs. Nothing special.
Now I'm asking myself:
Is there I standard class for Events that I can use, or do I have to write a new one by myself?
I know there ara java.awt.Event and AWTEvent. But I am not working directly at GUI level here. Furthermore we are using Swing at GUI level. So I'm not shure if it is a good idea to mix Swing and AWT.
Thx
Its ancient and simple, but you could use Observer/Obserable in java.util:
java.util
public class Observable extends Object
This class represents an observable
object, or "data" in the model-view
paradigm. It can be subclassed to
represent an object that the
application wants to have observed.
An observable object can have one or
more observers. An observer may be any
object that implements interface
Observer. After an observable instance
changes, an application calling the
Observable's notifyObservers method
causes all of its observers to be
notified of the change by a call to
their update method.
For more info, try http://www.javaworld.com/javaworld/jw-10-1996/jw-10-howto.html.
There's nothing special about events in Java. If your events are not GUI events, then it would be less confusing for you to use your own class and not mix them with java.awt.Events.
If you are using swing, you can take a look at EventBus:
The Event Bus is a single-process publish/subscribe event routing library, with Swing extensions. The EventBus is fully-functional, with very good API documentation and test coverage (80+%). It has been deployed in many production environments, including financial, engineering and scientific applications.
I've always used EventObject as the base class for my custom events. Here's what the JavaDoc says:
The root class from which all event state objects shall be derived.
All Events are constructed with a
reference to the object, the "source",
that is logically deemed to be the
object upon which the Event in
question initially occurred upon.
Kind of a standard solution in Swing apps is to maintain a list of event listeners in the class the event originates from. When the event occurs you iterate over the list and notify each listener of the event. So it can be something like this (I omitted the access modifiers and some of the type declarations for brevity):
class SomeClassInWhichTheEventOccurs {
List<MyListener> listeners;
void addListener(listener) { listeners.add(listener); }
void removeListener(listener) { listeners.remove(listener); }
void fireEvent(someEventParameters) {
foreach (listener in listeners) listener.eventOccured();
}
void someMethodInWhichTheEventOccurs() {
...
fireEvent(someEventParameters);
}
}
The event parameters can be just anything: you can create your own event class, reuse java.awt.Event, or pass some parameters of arbitrary types.
Swing is based upon AWT, so you have to mix it. The problem comes with mixing AWT heavyweight components with Swing lightweight components. Don't use AWT heavyweight components.
Just to be notified that something has changed javax.swing.event.ChangeListener is fine. In fact, so long as you are not using a library that assumes the beans model, you can ignore event classes and use a observer without an event object.

Java equivalent of Cocoa NSNotification?

I am writing a Java application using SWT widgets. I would like to update the state of certain widgets upon a certain event happening (for example, updating the data model's state).
Is there something in Java similar to Cocoa's NSNotificationCenter, where I can register an object to listen for notification events and respond to them, as well as have other objects "fire off" a notification?
Ok, suppose that for example, you want parts of your program to be notified when your Loader starts a scan, and when it finishes a scan (don't worry about what a Loader is, or what a scan is, these are examples from some code I have lying around from my last job). You define an interface, call it "ScanListener", like
public interface ScanListener
{
public void scanStarted();
public void scanCompleted();
}
Now the Loader defines a method for your other code to register for callbacks, like
public void addScanListener(ScanListener listener)
{
listeners.add(listener);
}
The Loader, when it starts a scan, executes the following code
for (ScanListener listener : listeners)
{
listener.scanStarted();
}
and when it finishes, it does the same thing with listener.scanCompleted();
The code that needs to be notified of these events implements that interface (either themselves, or in an internal class), and calls "loader.addScanListener(this)". Its scanStarted() and scanCompleted() methods are called at the appropriate times. You can even do this with callbacks that take arguments and/or return results. It's all up to you.
What sort of notifications are you looking for? If all you want is for one object to be able to tell anybody else "hey, I've changed, update accordingly", the easiest way is to use the existing Observer interface and Observable class. Or write your own with an interface that defines what you want to get called on the listeners from the one that's changed.
There's no pre-existing per-process service that dispatches events in java that's equivalent to the default NSNotificationCenter. In java, the type of the event is specified by the event object being a particular type (which also means that the notification method depends on that type) rather than using a string. Prior to generics, writing a general event dispatcher and receiver that is also typesafe isn't really possible (witness the proliferation of *Event classes and *EventListener interfaces in the AWT and Spring libraries).
There are some facilities for event dispatch. As Paul mentioned, there's java.util.Observable, which as you point out, requires subclassing. There's also java.beans.PropertyChangeSupport, which could be useful depending on your situation.
You could also write one yourself. The source for PropertyChangeSupport is likely available in the openjdk, and you could look at the abandoned Apache Commons Event project. Depending on your needs, you may have to worry about stuff like threading, seralization, memory leaks (ensuring deregistration or using weak references), and concurrent modification (iterate over a copy of your list of listeners, as a listener may decide to unregister itself in response to a change).
Now that generics exist in Java, a generic event dispatch library would be possible; however, I haven't come across any. Anyone?
There's actually a facility built in to Java that does exactly what you want, but it's not something you may have considered, and, to be honest, it is likely a bit heavyweight for what you want.
That said, however, it does exist.
It's JMX.
You create MBeans, and then others can register for events from those MBeans. The MBean can then send of a Notification.
I personally wouldn't consider using it for this case (I'd just pound out my own), but the facility is there and it well defined and documented.
Not Java, but the IPython project has a notification center written in Python here that you could use as a template for a Java version.
In Java this would be a provider firing notifications to its listeners. But Java does not offer the loose coupling you get with Cocoa's NSNotification because in Java providers and subscribers must have references to each other. Compare for this chapter 18 in "Learn Objective-C for Java Developers".
There is an implementation of IOS NSNotificationCenter in Java.
You can find sources code in :
This Github project

Categories

Resources