Ang*_*ker 10 java events event-handling
我有一个简单的课 - 将其称为动物.我想在Animal类中触发一个事件,并在我实例化Animal类的类中处理它.在事件处理程序中,我想传递一个Integer值
我该怎么做这样简单的事情?
Ada*_*ski 21
假设传递的整数是Animal类状态的一部分,那么执行此操作而非编写大量自己的代码的惯用方法是触发PropertyChangeEvent.您可以使用PropertyChangeSupport该类执行此操作,将代码减少到:
public class Animal {
// Create PropertyChangeSupport to manage listeners and fire events.
private final PropertyChangeSupport support = new PropertyChangeSupport(this);
private int foo;
// Provide delegating methods to add / remove listeners to / from the support class.
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l) {
support.removePropertyChangeListener(l);
}
// Simple example of how to fire an event when the value of 'foo' is changed.
protected void setFoo(int foo) {
if (this.foo != foo) {
// Remember previous value, assign new value and then fire event.
int oldFoo = this.foo;
this.foo = foo;
support.firePropertyChange("foo", oldFoo, this.foo);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我建议不要使用Observer/Observable因为它使代码难以理解/难以遵循:你经常需要在向下转换之前检查传递给Observer使用的参数的类型instanceof,并且很难看到特定Observer实现的事件类型期待通过查看其接口定义.更好地定义特定的侦听器实现和事件以避免这种情况.
小智 9
如果要避免从类似java.util.Observable的基类继承,请使用接口并让您的observable实现或委托接口的方法.
这是可观察的界面:
public interface IObservable
{
void addObserver(IObserver o);
void deleteObserver(IObserver o);
void notifyObservers(INotification notification);
}
Run Code Online (Sandbox Code Playgroud)
这是一个可以由真正的observables使用的辅助类:
import java.util.ArrayList;
import java.util.List;
public class Observable implements IObservable
{
private List<IObserver> observers;
@Override
public synchronized void addObserver(IObserver o)
{
if (observers == null)
{
observers = new ArrayList<IObserver>();
}
else if (observers.contains(o))
{
return;
}
observers.add(o);
}
@Override
public synchronized void deleteObserver(IObserver o)
{
if (observers == null)
{
return;
}
int idx = observers.indexOf(o);
if (idx != -1)
{
observers.remove(idx);
}
}
@Override
public synchronized void notifyObservers(INotification notification)
{
if (observers == null)
{
return;
}
for (IObserver o : observers)
{
o.update(notification);
}
}
}
Run Code Online (Sandbox Code Playgroud)
真正的可观察结果可能如下所示:
class Person implements IObservable
{
private final IObservable observable = new Observable();
@Override
public void setFirstName(String firstName) throws Exception
{
if (firstName == null || firstName.isEmpty())
{
throw new Exception("First name not set");
}
this.firstName = firstName;
notifyObservers(new Notification(this, getFirstNamePropertyId()));
}
@Override
public void addObserver(IObserver o)
{
observable.addObserver(o);
}
@Override
public void deleteObserver(IObserver o)
{
observable.deleteObserver(o);
}
@Override
public void notifyObservers(INotification notification)
{
observable.notifyObservers(notification);
}
private static final String FIRSTNAME_PROPERTY_ID = "Person.FirstName";
@Override
public String getFirstNamePropertyId()
{
return FIRSTNAME_PROPERTY_ID;
}
}
Run Code Online (Sandbox Code Playgroud)
这是观察者界面:
public interface IObserver
{
void update(INotification notification);
}
Run Code Online (Sandbox Code Playgroud)
最后,这是通知界面和基本实现:
public interface INotification
{
Object getObject();
Object getPropertyId();
}
public class Notification implements INotification
{
private final Object object;
private final Object propertyId;
public Notification(Object object, Object propertyId)
{
this.object = object;
this.propertyId = propertyId;
}
@Override
public Object getObject()
{
return object;
}
@Override
public Object getPropertyId()
{
return propertyId;
}
}
Run Code Online (Sandbox Code Playgroud)
一个简单的事件界面如下所示:
public interface AnimalListener {
public void animalDoesSomething(int action);
}
Run Code Online (Sandbox Code Playgroud)
Animal 需要管理其听众:
public class Animal {
private final List<AnimalListener> animalListeners = new ArrayList<AnimalListener>()
public void addAnimalListener(AnimalListener animalListener) {
animalListeners.add(animalListener);
}
}
Run Code Online (Sandbox Code Playgroud)
你的Animal创建类需要这样做:
public class AnimalCreator implements AnimalListener {
public void createAnimal() {
Animal animal = new Animal();
animal.addAnimalListener(this); // implement addListener in An
}
public void animalDoesSomething(int action) {
System.ot.println("Holy crap, animal did something!");
}
}
Run Code Online (Sandbox Code Playgroud)
现在Animal可以开火了.
public class Animal {
....
public void doSomething() {
for (AnimalListener animalListener : animalListeners) {
animalListener.animalDoesSomething(4);
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于像"触发事件"这样简单的事情来说,这看起来像很多代码但是可能触发事件并不简单.:)
当然,这种简单机制有各种扩展.
java.util.EventListener.public void animalDoesSomething(Animal animal, int action);.| 归档时间: |
|
| 查看次数: |
10605 次 |
| 最近记录: |