Pergunta para Mister M

Pessoal e possivel eu passar um METODO da classeA para a classeB e nessa classeB eu executar esse medoto da classeA??

se tiver como… alguem tem uma luz?? um metodo simples mesmo… sem passar parametro e sendo void…

valeus

Voce pode fazer um metodo (publico ou private pra não ferir o encapsulamento e usar os get’s e set’s) e passar a classeA como parametro para a classeB, instanciando um objeto da classeA vc acessa os metodos dela na classeB

[quote=fabioebner]Pessoal e possivel eu passar um METODO da classeA para a classeB e nessa classeB eu executar esse medoto da classeA??

se tiver como… alguem tem uma luz?? um metodo simples mesmo… sem passar parametro e sendo void…

valeus[/quote]

Cara desculpe se eu nao entendi a sua pergunta, Se sua intencao for manter o baixo acoplamento entre varias objetos do sistema,
eu acho que seu problema porde ser resolvido utilizando Injeção de dependência!
Se for isso , acho q essa seria a solucao mais adequada!
Se nao for isso de uma olhadinha no Spring pois ele tem muita coisa a oferecer, simplesmente fantastico!
abracos!

Não precisa nem passar como parâmetro, pode simplesmente instanciar um objeto da classe A dentro da classe B.
Ou então fazer um método static e chamar diretamente pela classe.

Entao Bani… o problema e q eu nao sei qual Classe eh, o metodo sim, sera sempre o mesmo nome, porem a classe nao… como eu faco isso???

tu tem algum exemplo??

valeu

O fato de passar como parametro seria se voce precisasse, por exemplo, atualizar uma outra tela de onde voce estava!
Quanto a pegar a classe sem saber qual é, e acessar um metodo de nome conhecido, da uma olhadinha nos metodos da classe Class e vc pode usar Reflection tb, tem um ótimo tutorial aqui no guj!

http://www.guj.com.br/java.tutorial.artigo.10.1.guj

Abraço

cara eu fiz o seguinte:

um projeto so com isso:

[code]public class ExecutaMetodo {
private Method metodo;
private Class<? extends Container> classe;
public void guargarMetodo(Class<? extends Container> classe, Method metodo){
this.metodo = metodo;
this.classe = classe;
}

public void executarMetodo() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
    this.metodo.invoke(classe, null);
}

}[/code]

e no meu projeto principal etou chamando assim:

[code] try {
Class objCls = Class.forName(“br.com.dnasolution.gui.GerenciarNaturezaJDL”);

        executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));
    } catch (NoSuchMethodException ex) {
        Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
    } catch (SecurityException ex) {
        Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ClassNotFoundException ex) {
        Logger.getLogger(GerenciarNaturezaJDL.class.getName()).log(Level.SEVERE, null, ex);
    }

executa.executarMetodo();[/code]

sendo que nesse projeto principal nessa classe eu tenho o seguinte metodo public void metodoX() { System.out.println("binhocao"); }

porem eu recebo o seguinte erro:

java.lang.IllegalArgumentException: object is not an instance of declaring class at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at testeexecutarmetodo.ExecutaMetodo.executarMetodo(ExecutaMetodo.java:25) at br.com.dnasolution.gui.GerenciarNaturezaJDL.jbtEditar(GerenciarNaturezaJDL.java:332) at br.com.dnasolution.gui.GerenciarNaturezaJDL.access$100(GerenciarNaturezaJDL.java:26) at br.com.dnasolution.gui.GerenciarNaturezaJDL$2.actionPerformed(GerenciarNaturezaJDL.java:142) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236) at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272) at java.awt.Component.processMouseEvent(Component.java:6038) at javax.swing.JComponent.processMouseEvent(JComponent.java:3265) at java.awt.Component.processEvent(Component.java:5803) at java.awt.Container.processEvent(Container.java:2058) at java.awt.Component.dispatchEventImpl(Component.java:4410) at java.awt.Container.dispatchEventImpl(Container.java:2116) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916) at java.awt.Container.dispatchEventImpl(Container.java:2102) at java.awt.Window.dispatchEventImpl(Window.java:2429) at java.awt.Component.dispatchEvent(Component.java:4240) at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:177) at java.awt.Dialog$1.run(Dialog.java:1039) at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209) at java.awt.EventQueue.dispatchEvent(EventQueue.java:597) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160) at java.awt.EventDispatchThread.run(EventDispatchThread.java:121) ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]

ajudae please P

[quote=fabioebner]cara eu fiz o seguinte:

um projeto so com isso:

[code]public class ExecutaMetodo {
private Method metodo;
private Class<? extends Container> classe;
public void guargarMetodo(Class<? extends Container> classe, Method metodo){
this.metodo = metodo;
this.classe = classe;
}

public void executarMetodo() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
    this.metodo.invoke(classe, null);
}

}[/code]

[/quote]

No invoque vc tem que passar um Objeto da classe certa e não a classe em si. Ou seja, o método tem que ser invocado em cima de algum objeto real.

vc precisa alterar para

[code]public class ExecutaMetodo<T extends Container {
private Method metodo;
private Class classe;

public void guardarMetodo(Class<T> classe, Method metodo){
    this.metodo = metodo;
    this.classe = classe;
}

public void executarMetodo(T container) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
    this.metodo.invoke(container, null);
}

}[/code]

e

[code] try {
Class objCls = Class.forName(“br.com.dnasolution.gui.GerenciarNaturezaJDL”);

         ExecutaMetodo executa = new ExecutaMetodo()
         
         executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));  

         T instance = objCls.newInstance();

         executa.executaMetodo(instance);

[/code]

Tem que colocar cast corretos no Class forname. mas o ponto é que vc tem que criar um objeto e invocar o método sobre ele.

Cara eu nao manjo de reflection… logo ele esta dando uns erros: tipo

Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");  

fala q nao acha a classe T

T instance = objCls.newInstance();

mesma coisa. vale lembrar q a classe q executa o metodo nao e do mesmo projeto e apenar um jar q eu vou chamar no meu projeto principal…

na classe ExecutaMetodo do projeto A

[code]public class ExecutaMetodo {
private Method metodo;
private Class classe;
public void guargarMetodo(Class classe, Method metodo){
this.metodo = metodo;
this.classe = classe;
}

public void executarMetodo(T container) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
    this.metodo.invoke(container, null);
}

}[/code]
nao eu erro

e o codigo [code]
Class objCls = Class.forName(“br.com.dnasolution.gui.GerenciarNaturezaJDL”);

        ExecutaMetodo executa = new ExecutaMetodo();   
           
        executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));     


            T instance = objCls.newInstance();
            
            executa.executarMetodo(instance);[/code]

da classe GerenciarFuncionarioJDL do projeto B e q da os erros.

valeu

Isso não se resolve com o uso de interfaces?

public interface Comum {
        public void metodoX();
}


public class A implements Comum {
        public void metodoX() {
        }

}

public class Whatever implements Comum {
        public void metodoX() {
        }

}


public class Test {
         public void exec(Comum comum) {
                comum.metodoX();
         }
}

Interface e uma otima solução, essa forma que o g4j abordou vc estará usando padrão de projeto Strategy, tornando sua aplicação muito mais flexivel

[quote=fabioebner]Cara eu nao manjo de reflection… logo ele esta dando uns erros: tipo

Class<T> objCls = Class.forName("br.com.dnasolution.gui.GerenciarNaturezaJDL");  

fala q nao acha a classe T

T instance = objCls.newInstance();

[/quote]

T não é uma classe é um tipo generico.
Se não funciona retire os T. Use Class em vez de Class e Object em vez de T.

E mlkao nada feito… agora eu recebo o seguinte erro:

[quote]03/10/2008 09:08:57 br.com.dnasolution.gui.GerenciarFuncionarioJDL
SEVERE: null
java.lang.InstantiationException: br.com.dnasolution.gui.GerenciarNaturezaJDL
at java.lang.Class.newInstance0(Class.java:340)
at java.lang.Class.newInstance(Class.java:308)
at br.com.dnasolution.gui.GerenciarFuncionarioJDL.(GerenciarFuncionarioJDL.java:46)
at notas.Main.main(Main.java:31)
[/quote]

o meu codigo esta asim:

[code] Class objCls;

        ExecutaMetodo executa = new ExecutaMetodo();   
    try {
        objCls = Class.forName("br.com.dnasolution.gui.GerenciarFuncionarioJDL");
      executa.guargarMetodo(objCls, this.getClass().getMethod("metodoX", new Class[]{}));     


            Object instance = objCls.newInstance();
            
            executa.executarMetodo(instance);             
    } catch (Exception ex) {
        Logger.getLogger(GerenciarFuncionarioJDL.class.getName()).log(Level.SEVERE, null, ex);
    }
           [/code]

e a classe q vai executar o metodo esta assim:

[code] private Method metodo;
private Class classe;
public void guargarMetodo(Class classe, Method metodo){
this.metodo = metodo;
this.classe = classe;
}

public void executarMetodo(Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{
    this.metodo.invoke(obj, null);
}

[/code]

obs a classe q estou tentando instanciar e essa

public class GerenciarFuncionarioJDL extends javax.swing.JDialog {

abracos

Cara, precisa mesmo fazer com reflection? Não pensou na possibilidade de usar interface?

g4j entao cara nao da para fazer com interface nao… pq o nome do metodo vai ser sempre o mesmo porem o conteudo muda de classe para classe, e a classe q vai executar esse metodo sabe qual classe eu esou recebendo ou o conteudo do metodo… apenas executar. entendeu

Mas é isso mesmo que o modelo com interfaces se propõe. Vc não precisa saber que classe concreta vai executar, mas vc sabe que é uma classe que implementa a interface Comum, que tem o tal metodoX. Aí em todas as classes que vc quer passar para a execução vc implementa a interface Comum, que força vc a implementar o metodoX.

interface Comum {
	public void metodoX();
}

class GerenciarFuncionarioJDL implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de GerenciarFuncionarioJDL");
	}
}

class QualquerClasseQueTenhaMetodoX implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de QualquerClasseQueTenhaMetodoX");
	}
}

class MaisUmaQueTenhaMetodoX implements Comum {
	public void metodoX() {
		System.out.println("Execução métodoX de MaisUmaQueTenhaMetodoX");
	}
}


class ExecutaMetodo {
	public void executar(Comum comum) {
		comum.metodoX();
	}
}


public class ExecutaMetodoTest {
	public static void main(String[] args) {
		ExecutaMetodo executaMetodo = new ExecutaMetodo();
	
		executaMetodo.executar(new GerenciarFuncionarioJDL());
		executaMetodo.executar(new QualquerClasseQueTenhaMetodoX());
		executaMetodo.executar(new MaisUmaQueTenhaMetodoX());
	}
}

Seu problema é facilmente resolvido com a utilização de interface sim… você está confundindo as coisas.

pessoal vcs q nao entenderam… eu tenho q passar esse metodo para OUTRA classe executar ele… eu tenho a CLASSEA que tem o metodoX, a CLASSEB tbm tem o metodoX(porem com outra funcionalidade) a CLASSEC tem o metodoX (com outra funciondalidade)

agora eu tenho uma CLASSEEXECUTAMETODOX q recebe o metodo X e dependendo de alguma verificacao executa ou nao o metodoX entendeu???

o meu problema q e eu tenho q criar uma classe q executa o metodo de outra classe sem conhecer a mesma… por isso do reflection…

eu recebo uma classe QUALQUER e executo o metodoX daquela classe. sem precisar saber o q ele faz ou nao

Vamos por partes:

Não precisa passar o método, passa uma classe que implementa a interface que provê garantia de implentação do metodoX

Exatamente!!! Vc não sabe qual é!

a tal classe que executa o metodoX é essa aqui! só que vc passa a classe que implementa a interface Comum pro método “executar” ao invés de passar um método.

 class ExecutaMetodo {  

     public void executar(Comum comum) {  
         //executa o metodoX de QUALQUER classe que implementa a interface Comum.

         //VERIFICA O QUE QUER QUE SEJA:
         if(.........) {
                comum.metodoX();  
         }
     }  
 }  

[quote=fabioebner] “…” eu tenho a CLASSEA que tem o metodoX, a CLASSEB tbm tem o metodoX(porem com outra funcionalidade) a CLASSEC tem o metodoX (com outra funciondalidade) “…”
[/quote]

São essas: Note que todas elas implementam a interface Comum, portanto, garante que ela tenha o metodoX implementado.

 class ClasseA implements Comum {  //CLASSEA !
     public void metodoX() {  
         System.out.println("Execução métodoX de GerenciarFuncionarioJDL");  
     }  
 }  
   
 class ClasseB implements Comum {  //CLASSEB !
     public void metodoX() {  
         System.out.println("Execução métodoX de QualquerClasseQueTenhaMetodoX");  
     }  
 }  
   
 class ClasseXYZ implements Comum {  //CLASSE XYZ!
     public void metodoX() {  
         System.out.println("Execução métodoX de MaisUmaQueTenhaMetodoX");  
     }  
 }  

Sacou?

boa mlkao… acho q funcionou sim. .pelo menos o teste q eu fiz aqui deu certo… deixa eu fazer o punk agora… so uma coisa… como a classe q tem o metodoX e a classe q vai executar estao em PROJETOS diferentes eu tenho q ter a mesma interface no mesmo pacote em ambos os projetos neh??

pq a classe q executa o metodo nao e a principal… e um componente da principal entendeu