J'utilise un framework appelé Processing qui est essentiellement une applet Java. Il a la capacité de faire des événements clés, car Applet peut. Vous pouvez également lancer vos propres rappels de sortes dans le parent. Je ne le fais pas en ce moment et peut-être que c'est la solution. Pour l'instant, je cherche une solution plus POJO. J'ai donc écrit quelques exemples pour illustrer ma question.Regarder une variable pour les changements sans polling
Veuillez ignorer l'utilisation des événements de clé sur la ligne de commande (console). Certes, ce serait une solution très propre, mais ce n'est pas possible sur la ligne de commande et mon application réelle n'est pas une application en ligne de commande. En fait, un événement clé serait une bonne solution pour moi, mais j'essaie de comprendre les événements et d'interroger au-delà des problèmes spécifiques au clavier.
Ces deux exemples retournent un booléen. Quand le booléen se retourne, je veux tirer quelque chose une fois. Je pourrais envelopper le booléen dans un objet, donc si l'objet change, je pourrais déclencher un événement aussi. Je ne veux pas interroger avec une instruction if() inutilement.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/*
* Example of checking a variable for changes.
* Uses dumb if() and polls continuously.
*/
public class NotAvoidingPolling {
public static void main(String[] args) {
boolean typedA = false;
String input = "";
System.out.println("Type 'a' please.");
while (true) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
try {
input = br.readLine();
} catch (IOException ioException) {
System.out.println("IO Error.");
System.exit(1);
}
// contrived state change logic
if (input.equals("a")) {
typedA = true;
} else {
typedA = false;
}
// problem: this is polling.
if (typedA) System.out.println("Typed 'a'.");
}
}
}
L'exécution de cette sortie:
Type 'a' please.
a
Typed 'a'.
Sur certains forums les gens ont suggéré d'utiliser un observateur. Et bien que cela décompose le gestionnaire d'événements de la classe observée, j'ai toujours une boucle if() sur forever.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Observable;
import java.util.Observer;
/*
* Example of checking a variable for changes.
* This uses an observer to decouple the handler feedback
* out of the main() but still is polling.
*/
public class ObserverStillPolling {
boolean typedA = false;
public static void main(String[] args) {
// this
ObserverStillPolling o = new ObserverStillPolling();
final MyEvent myEvent = new MyEvent(o);
final MyHandler myHandler = new MyHandler();
myEvent.addObserver(myHandler); // subscribe
// watch for event forever
Thread thread = new Thread(myEvent);
thread.start();
System.out.println("Type 'a' please.");
String input = "";
while (true) {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
try {
input = br.readLine();
} catch (IOException ioException) {
System.out.println("IO Error.");
System.exit(1);
}
// contrived state change logic
// but it's decoupled now because there's no handler here.
if (input.equals("a")) {
o.typedA = true;
}
}
}
}
class MyEvent extends Observable implements Runnable {
// boolean typedA;
ObserverStillPolling o;
public MyEvent(ObserverStillPolling o) {
this.o = o;
}
public void run() {
// watch the main forever
while (true) {
// event fire
if (this.o.typedA) {
setChanged();
// in reality, you'd pass something more useful
notifyObservers("You just typed 'a'.");
// reset
this.o.typedA = false;
}
}
}
}
class MyHandler implements Observer {
public void update(Observable obj, Object arg) {
// handle event
if (arg instanceof String) {
System.out.println("We received:" + (String) arg);
}
}
}
L'exécution de cette sortie:
Type 'a' please.
a
We received:You just typed 'a'.
je serais ok si le cas() a été un NOOP sur la CPU. Mais c'est vraiment comparer chaque passe. Je vois la charge réelle du processeur. C'est aussi mauvais que le sondage. Je peux peut-être l'étrangler avec un sommeil ou comparer le temps écoulé depuis la dernière mise à jour, mais ce n'est pas un événement. C'est juste moins de sondage. Alors, comment puis-je faire plus intelligent? Comment puis-je regarder un POJO pour les changements sans interroger?
En C# il semble y avoir quelque chose d'intéressant appelé propriétés. Je ne suis pas un gars C# alors peut-être que ce n'est pas aussi magique que je pense.
private void SendPropertyChanging(string property)
{
if (this.PropertyChanging != null) {
this.PropertyChanging(this, new PropertyChangingEventArgs(property));
}
}
Remarque: Observable/Observer est assez similaire à la gestion des événements. Ceci est un modèle de gestionnaire d'événements/observateur hybride, qui est très facile à utiliser. Il peut être encore amélioré, de sorte que le "firePropertyChanged" utilise la réflexion pour modifier le champ privé. Alors toutes les méthodes de setter sont très propres et maintenables, bien que les performances puissent diminuer. – Pindatjuh