Метод on
может заменить как bind
, так и delegate
в зависимости от того, как он используется (а также click
, поскольку bind
может заменить это):
.click(handler) == .on('click', handler)
.bind('click', handler) == .on('click', handler)
.delegate('click', '#id', handler) == .on('click', '#id', handler)
Ни click
, delegate
или bind
до сих пор перешли на устаревшую страницу . Я сомневаюсь, что метод click
когда-либо будет.
Да, обработка событий - ключ к решению вашей проблемы. Во фрагменте кода C #, который вы показываете, также используется обработка событий, чтобы сообщить слушателям об изменении свойства. В Java также есть PropertyChangeEvent, который используется для большинства компонентов. (Например: компоненты Swing используют их).
Однако вы можете сделать это вручную: (хотя это уже не POJO, а скорее Java Bean)
EventBean.java :
import java.util.LinkedList;
import java.util.List;
public class EventBean {
private final List<Listener> listeners = new LinkedList<Listener>();
protected final <T> void firePropertyChanged(final String property,
final T oldValue, final T newValue) {
assert(property != null);
if((oldValue != null && oldValue.equals(newValue))
|| (oldValue == null && newValue == null))
return;
for(final Listener listener : this.listeners) {
try {
if(listener.getProperties().contains(property))
listener.propertyChanged(property, oldValue, newValue);
} catch(Exception ex) {
// log these, to help debugging
ex.printStackTrace();
}
}
}
public final boolean addListener(final Listener x) {
if(x == null) return false;
return this.listeners.add(x);
}
public final boolean removeListener(final Listener x) {
return this.listeners.remove(x);
}
}
Listener.java :
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
// Must be in same package as EventBean!
public abstract class Listener {
private final Set<String> properties;
public Listener(String... properties) {
Collections.addAll(this.properties = new TreeSet<String>(), properties);
}
protected final Set<String> getProperties() {
return this.properties;
}
public abstract <T> void propertyChanged(final String property,
final T oldValue, final T newValue);
}
И реализуйте свой класс следующим образом:
public class MyBean extends EventBean {
private boolean typedA;
public void setTypedA(final boolean newValue) {
// you can do validation on the newValue here
final boolean oldValue = typedA;
super.firePropertyChanged("typedA", oldValue, newValue);
this.typedA = newValue;
}
public boolean getTypedA() { return this.typedA; }
}
Который вы можете использовать как:
MyBean x = new MyBean();
x.addListener(new Listener("typedA") {
public <T> void propertyChanged(final String p,
final T oldValue, final T newValue) {
System.out.println(p + " changed: " + oldValue + " to " + newValue);
// TODO
}
});
x.setTypedA(true);
x.setTypedA(false);
x.setTypedA(true);
x.setTypedA(true);
Вы неправильно понимаете шаблон наблюдателя, если ваша реализация использует опрос. В шаблоне наблюдателя метод, который изменяет состояние субъекта, будет вызывать уведомление подписанных наблюдателей до его завершения.
Очевидно, это означает, что субъект должен поддерживать шаблон наблюдателя, вы не можете использовать какой-либо старый простой объект Java в качестве субъекта в шаблоне наблюдателя.
Вы также можете посмотреть пример википедии для шаблона наблюдателя .
Фактически, дополнительный поток не нужен. Вы должны позволить ObserverStillPolling
расширить Observable
и уведомить наблюдателей, когда input.equals ("a")
.
Да, это означает, что сам объект POJO должен расширять Observable
и уведомлять самих наблюдателей.
Тем не менее, Observer / Observable
на самом деле плохо спроектированы. Я бы посоветовал создать свой собственный интерфейс PropertyChangeListener
и позволить вашему POJO реализовать его. Затем позвольте POJO зарегистрировать себя в наблюдателе во время построения или сделать это динамически, проверив где-нибудь instanceof PropertyChangeListener
, если применимо.
Возможно, решение - wait ()
/ notify ()
или одна из утилит параллелизма Java. Эти конструкции избегают опроса «занято-ожидание», о котором, кажется, идет речь.
Они используются с несколькими потоками. Один поток доставляет событие, другие на него отвечают. Вот пример:
class SyncQueue {
private final Object lock = new Object();
private Object o;
/* One thread sends "event" ... */
void send(Object o)
throws InterruptedException
{
if (o == null)
throw new IllegalArgumentException();
synchronized (lock) {
while (this.o != null)
lock.wait();
this.o = o;
lock.notifyAll();
}
}
/* Another blocks (without burning CPU) until event is received. */
Object recv()
throws InterruptedException
{
Object o;
synchronized (lock) {
while (this.o == null)
lock.wait();
o = this.o;
this.o = null;
lock.notifyAll();
}
return o;
}
}