import java.util.*;// An interface to be implemented by everyone interested in "Hello" eventsinterfaceHelloListener{void someoneSaidHello();}// Someone who says "Hello"classInitiater{privateList<HelloListener> listeners =newArrayList<HelloListener>();publicvoid addListener(HelloListener toAdd){
listeners.add(toAdd);}publicvoid sayHello(){System.out.println("Hello!!");// Notify everybody that may be interested.for(HelloListener hl : listeners)
hl.someoneSaidHello();}}// Someone interested in "Hello" eventsclassResponderimplementsHelloListener{@Overridepublicvoid someoneSaidHello(){System.out.println("Hello there...");}}classTest{publicstaticvoid main(String[] args){Initiater initiater =newInitiater();Responder responder =newResponder();
initiater.addListener(responder);
initiater.sayHello();// Prints "Hello!!!" and "Hello there..."}}
Existe uma razão legítima para que stackoverflow.com/suggested-edits/237242 não tenha passado? Ele mostra como fazer isso com 2 classes, como a pergunta originalmente feita.
GlassGhost
2
E se vários threads estiverem gerando os eventos de origem, isso será sincronizado corretamente?
Mike G
Depende da siruação. Cada ouvinte será notificado de acordo com a ordem em que se registrou. (Btw, eu não entendo o que você quer dizer com vários segmentos aqui O código ouvinte será exectued no mesmo segmento que causou o evento para ocorrer..)
aioobe
8
@ GllGhost: Foi rejeitado porque era basicamente uma reescrita total. As edições na resposta de outra pessoa são boas se corrigirem erros de digitação, formatação e links quebrados, mas não devem alterar radicalmente o conteúdo. (Algumas exceções se aplicam para as mensagens marcadas como "wiki comunidade".)
Chao
1
O java não tem nada incorporado para isso? Eu realmente preferiria fazer isso em padrão abstrato, não implementar o loop for para todos os eventos.
Tomáš Zato - Restabelece Monica
27
O que você deseja é uma implementação do padrão observador . Você pode fazer isso sozinho ou usar classes java como java.util.Observerejava.util.Observable
Existem três maneiras diferentes de configurar isso:
Thrower dentro de Catcher
Catcher dentro de Thrower
Throwere Catcherdentro de outra classe neste exemploTest
O EXEMPLO DO GITHUB DO TRABALHO QUE EU ESTOU CITANDO O padrão é a Opção 3, para tentar os outros "Optional"simplesmente descomente obloco de código da classe"" que você quer que seja a principal e defina essa classe como a${Main-Class}variável nobuild.xmlarquivo:
4 coisas necessárias para jogar código lateral:
import java.util.*;//import of java.util.event//Declaration of the event's interface type, OR import of the interface,//OR declared somewhere else in the packageinterfaceThrowListener{publicvoidCatch();}/*_____________________________________________________________*/classThrower{//list of catchers & corresponding function to add/remove them in the listList<ThrowListener> listeners =newArrayList<ThrowListener>();publicvoid addThrowListener(ThrowListener toAdd){ listeners.add(toAdd);}//Set of functions that Throw Events.publicvoidThrow(){for(ThrowListener hl : listeners) hl.Catch();System.out.println("Something thrown");}////Optional: 2 things to send events to a class that is a member of the current class... go to github link to see this code ...}
2 Coisas necessárias em um arquivo de classe para receber eventos de uma classe
/*_______________________________________________________________*/classCatcherimplementsThrowListener{//implement added to class//Set of @Override functions that Catch Events@OverridepublicvoidCatch(){System.out.println("I caught something!!");}////Optional: 2 things to receive events from a class that is a member of the current class... go to github link to see this code ...}
@ GllGhost: O problema é que mainé estático, e não existe thisuma função estática. Você precisa criar um new Catcher1()lugar e passar essa instância. 1.5 também não permitia thisem um contexto estático; Tenho certeza de que nunca foi permitido.
cHao 23/01
6
@ GllGhost: O código que usa thisestá em um construtor, não em main. É por isso que funciona. Mova para main, e eu garanto que não. É o que as pessoas tentam lhe dizer e sua resposta está tentando fazer. Eu não dou a mínima para o que está no github - eu me importo com o que está no SO. E o que você tem no SO está quebrado.
cHao 3/08/14
7
@ GllGhost: Eu não acho que sua resposta seja inadequada no geral. O problema que vejo com isso é que o código não trabalho como é - você está tentando usar thisa partir main, que não irá compilar em qualquer versão lançada do Java. Se essa parte estava em um construtor ou se maincriou a new Catcher1()e usou isso em vez de this, deve funcionar, mesmo em 1.6+.
cHao 3/08/14
6
@GlassGhost: "Um método declarado staticé chamado de método de classe. Um método de classe é sempre invocado sem referência a um objeto específico. Uma tentativa de referenciar o objeto atual usando a palavra-chave thisou a palavra-chave superou os parâmetros de tipo de qualquer ambiente circundante. declaração no corpo de um método de classe resulta em um erro em tempo de compilação. " - JLS para Java 5, §8.4.3.2
cHao 03/08/14
31
Este é um dos estilos de código mais estranhos que eu já vi
Eric
4
O seguinte não é exatamente o mesmo, mas semelhante, eu estava procurando por um trecho para adicionar uma chamada ao método da interface, mas encontrei esta pergunta, então decidi adicionar esse trecho para aqueles que o pesquisavam como eu e encontrei esta pergunta :
Respostas:
Você provavelmente deseja examinar o padrão de observador .
Aqui está um exemplo de código para você começar:
Artigo relacionado: Java: Criando um Evento Customizado
fonte
O que você deseja é uma implementação do padrão observador . Você pode fazer isso sozinho ou usar classes java como
java.util.Observer
ejava.util.Observable
fonte
Existem três maneiras diferentes de configurar isso:
Thrower
dentro deCatcher
Catcher
dentro deThrower
Thrower
eCatcher
dentro de outra classe neste exemploTest
O EXEMPLO DO GITHUB DO TRABALHO QUE EU ESTOU CITANDO O padrão é a Opção 3, para tentar os outros "
Optional
"simplesmente descomente obloco de código da classe"" que você quer que seja a principal e defina essa classe como a${Main-Class}
variável nobuild.xml
arquivo:4 coisas necessárias para jogar código lateral:
2 Coisas necessárias em um arquivo de classe para receber eventos de uma classe
fonte
main
é estático, e não existethis
uma função estática. Você precisa criar umnew Catcher1()
lugar e passar essa instância. 1.5 também não permitiathis
em um contexto estático; Tenho certeza de que nunca foi permitido.this
está em um construtor, não emmain
. É por isso que funciona. Mova paramain
, e eu garanto que não. É o que as pessoas tentam lhe dizer e sua resposta está tentando fazer. Eu não dou a mínima para o que está no github - eu me importo com o que está no SO. E o que você tem no SO está quebrado.this
a partirmain
, que não irá compilar em qualquer versão lançada do Java. Se essa parte estava em um construtor ou semain
criou anew Catcher1()
e usou isso em vez dethis
, deve funcionar, mesmo em 1.6+.static
é chamado de método de classe. Um método de classe é sempre invocado sem referência a um objeto específico. Uma tentativa de referenciar o objeto atual usando a palavra-chavethis
ou a palavra-chavesuper
ou os parâmetros de tipo de qualquer ambiente circundante. declaração no corpo de um método de classe resulta em um erro em tempo de compilação. " - JLS para Java 5, §8.4.3.2O seguinte não é exatamente o mesmo, mas semelhante, eu estava procurando por um trecho para adicionar uma chamada ao método da interface, mas encontrei esta pergunta, então decidi adicionar esse trecho para aqueles que o pesquisavam como eu e encontrei esta pergunta :
O uso é o seguinte:
fonte