Equivalente do delegate (C#) em Java - Jacob

Boa tarde Pessoal,

Estou tentando fazer a comunicação de um sensor de biometria com Java, para isso estou usando Jacob para acessar a ocx que ele me forneceu e me passou um programinha em C# com exemplo funcionando e codigo fonte do mesmo.
Porem que ele é baseado em evento, como faria isso em Java utlizando jacob

sensor.OnEnroll += new AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEventHandler(sensor_OnEnroll);

private void sensor_OnEnroll(object sender, AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEvent e){...}

Obrigado

EDIT (Moderador) - Separei o neologismo “equilate” em duas palavras, “equivalente” e “delegate”.

Java não suporta delegates. Deve haver uma outra maneira de mapear as mensagens do ocx.

Olá

Vivendo e aprendendo… mais de 40 anos de TI e acho que nunca ouvi falar disto…

Afinal, o que é “equilate”?

[]s
Luca

Ele quis dizer “equivalente” ou “delegate”?

De qualquer maneira, mesmo o Jacob não é adequado para receber um evento de uma OCX. Uma OCX requer ser hospedada em um ActiveX Container, e isso normalmente requer uma janela do Windows (não uma do Swing).

Você terá de desenhar sua tela usando SWT, não Swing:

http://help.eclipse.org/galileo/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/ole/win32/OleControlSite.html

Como é que se usa isso? Não tenho a menor idéia. Nunca fiz nada em SWT.

Veja o seguinte artigo:

Olá,
segundo http://msdn.microsoft.com/en-us/library/ms173171%28VS.80%29.aspx o delegate é um método que aponta para outro e se comporta como o método apontado :shock: acho que isso não é possível atualmente… isso vai ser possível com os tais closures?

Att.

O pouco de C# que eu sei é o seguinte: todo evento de um ActiveX (código nativo, ou em Dot-Netês, “código não gerenciado”) é mapeado, em .NET, para um “event delegate” (um método especial que serve, basicamente, para tratar eventos de componentes).

No caso de você usar um ActiveX em Java, usando o componente em um form do SWT, o evento do ActiveX é mapeado para um listener normal Java (como se fosse um tratamento de evento de clique de botão no Swing, que você deve estar acostumado a usar). Isso é o que concluí da leitura daquele documento que lhe apontei ( http://www.eclipse.org/articles/article.php?file=Article-ActivexSupportInSwt/index.html ).

Portanto, se você usar um form SWT no seu programa, é relativamente fácil você poder inserir uma OCX. Provavelmente você não deve ter feito um programa gigante em Swing que você acabe perdendo ainda, ou seja, é melhor desenhar agora suas telas em SWT antes que seja tarde.

A pressa me fez escrever errado, é equivalente.

E para piorar eu vou ter que colocar isso em uma aplicação web. :frowning:

vo dar uma olhada nesse artigo.

Obrigado

Será que se jogar em um applet não dá certo daí? :?

[quote=alissonvla]A pressa me fez escrever errado, é equivalente.

E para piorar eu vou ter que colocar isso em uma aplicação web. :frowning:

vo dar uma olhada nesse artigo.

Obrigado[/quote]

Em uma aplicação Web? Então você só tem uma saída. Você precisa criar uma aplicação ActiveX assinada digitalmente que possa chamar esse outro ActiveX; talvez tenha de escrever esse ActiveX em VB 6.0 (argh ugh argh) ou em C++ (argh ugh arg) ou talvez em Delphi ou talvez em C# (não sei como é que se faz um ActiveX em C# ou então um código C# normal que possa ser carregada no browser e possa acessar uma OCX). Isso vai aparecer no browser do usuário, é isso mesmo? Ugh. Provavelmente você vai ter de falar com o cara que fornece essas OCXs e ver se algum cliente dele já tentou fazer funcionar isso no browser; acho que você vai ter é um monte de problemas.

Um delegate nada mais é que um ponteiro para um método ou função, e isso pode ser escrito em c++ facilmente, ou qualquer outra linguagem que suporte ponteiros.
Eu imagino que possa ser mapeada em java usando jni(isso com certeza dará certo), ou usando um toolkit nativo como swt como o pessoal citou acima, que já mapeia sinais do windows.

Você pode inverter o problema. Já que seu sistema precisa de instalação de qualquer jeito (pois precisa de um hardware específico), escreva um programa (talvez em C# ou então Java SWT) que hospede o browser (IE ou Mozilla Firefox) e também a OCX que você precisa para fazer a autenticação. Esse browser não teria a barra de endereços e seria usado só para acessar o seu site. Quando você precisar entrar no site, a OCX controla o acesso.

o meu grande problema vai ser, como fazer esse delegate no Java… :frowning:

Quiá quiá quiá - esse é o menor do seus problemas, na verdade não é problema algum. Basta estudar um pouquinho da sua OCX e C# para entender que você não precisa se preocupar com essa história de delegates. Se você for usar a OCX com SWT, e ler direitinho aquele artigo que está no site do Eclipse, vai ver que o equivalente são simples Listeners do Java. Não se preocupe com isso - você vai ter é outros problemas.

Java não suporta ponteiros e também não suporta delegates. Deve existir um mapeamento próprio em alguma api como o swt.

Basicamente o que ocorre é o seguinte:

OCX é uma tecnologia bem antiga (que apareceu, pasmem, no tempo do Windows 3.0, se não me engano, com o VB 3) que define componentes visuais codificados, normalmente, em C++, Delphi ou VB 6. Um componente OCX é uma espécie de objeto onde estão definidas propriedades (como as propriedades de um JavaBean, digamos) e eventos (como os eventos que você pode associar a um componente visual do Java, que normalmente requerem algum tipo de Listener).

Quando você tem algo como;

    sensor.OnEnroll += new AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEventHandler(sensor_OnEnroll);  
      
    private void sensor_OnEnroll(object sender, AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEvent e){...}  

isso vai ser traduzido, pelo SWT, para algo parecido com isso (não exatamente assim, é claro!)

sensor.addActionListener (new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        sensor_OnEnroll (e);
});
....

private void sensor_OnEnroll (ActionEvent e) {
}

[quote=entanglement]Basicamente o que ocorre é o seguinte:

OCX é uma tecnologia bem antiga (que apareceu, pasmem, no tempo do Windows 3.0, se não me engano, com o VB 3) que define componentes visuais codificados, normalmente, em C++, Delphi ou VB 6. Um componente OCX é uma espécie de objeto onde estão definidas propriedades (como as propriedades de um JavaBean, digamos) e eventos (como os eventos que você pode associar a um componente visual do Java, que normalmente requerem algum tipo de Listener).

Quando você tem algo como;

    sensor.OnEnroll += new AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEventHandler(sensor_OnEnroll);  
      
    private void sensor_OnEnroll(object sender, AxZKFPEngXControl.IZKFPEngXEvents_OnEnrollEvent e){...}  

isso vai ser traduzido, pelo SWT, para algo parecido com isso (não exatamente assim, é claro!)

[code]
sensor.addActionListener (new ActionListener() {
public void actionPerformed(ActionEvent e) {
sensor_OnEnroll (e);
});

private void sensor_OnEnroll (ActionEvent e) {
}
[/code][/quote]

Não necessariamente dessa forma. Eu imagino que o swt deve estar preparado para isso, mas não tenho certeza. Esses sinais são próprios do controle, e não do swt ou do java. O toolkit deve ter implementações específicas para lidar com elas. Se não tiver não dá para criar uma solução adequada, e vai ser preciso usar jni, já que um activex nada mais é que uma dll com um ponto de entrada um pouco diferente.

OK, vou copiar o código que o SWT usa para algum evento que o controle OCX requer que seja implementado.
Fonte:

	// Respond to ProgressChange events in the Web Browser by updating the applications Progress bar
	OleControlSite controlSite = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
	OleAutomation automation = new OleAutomation(controlSite);
	int ProgressChange = 108; //0x6C - obtained from the type library
	ProgressBar progressBar = new ProgressBar(shell, SWT.BORDER);
	controlSite.addEventListener(ProgressChange, new OleListener() {
		public void handleEvent(OleEvent event) {
			if (event.detail != ProgressChange) return;
			Variant progress = event.arguments[0];
			Variant maxProgress = event.arguments[1];
			if (progress == null || maxProgress == null) return;
			
			progressBar.setMaximum(maxProgress.getInt());
			progressBar.setSelection(progress.getInt());
		}
	});

De fato, você precisa criar uma classe que implementa OleListener, e pôr o código para seu evento em um método handleEvent(OleEvent event). Como se vê, o SWT transformou o tratamento de eventos da OCX em algo que realmente do jeitinho costumeiro do Java.