Reflection-Invoke, como passar como tipo de parâmetro uma classe que fiz?

Bem, não sei como explicar bem, mas seria algo do tipo assim:

Tenho uma classe item, que para simplificar, seria basicamente algo do tipo:

public class item {
public item(){
}
}

Ai numa instancia, eu quero chamar um metodo que está em outra instancia, resumidamente o problema está aqui:

Class cls = Class.forName("jogo.inventorio"); //ate aki tudo bem, é onde estão os metodos que vo invocar....
Method mtd1 = cls.getMethod("setItem", item.class); //Aqui eu não se está certo, pois o parâmetro desse metodo é do tipo item...
Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE); //Aqui é um parâmetro do tipo Integer. ok.
Object obj1 = mtd1.invoke(pai, it); //Aqui provavelmente é a causa do problema. Informando que não coloquei aqui, mas já instanciei o "it" como tipo, item.
Object obj2 = mtd2.invoke(pai, 1); //Aqui vai tudo bem...

Dá um erro assim: object is not an instance of declaring class.

Qualquer luz é bem-vinda. Obrigado desde já.

Voce tem certeza que it é um objeto do tipo Item? Ou voce apenas fez um cast de outra coisa e esta recebendo um class cast exception?

Fiz um pequeno exemplo p/ ajudar.

public class Main {
	public static void main(String[] args) throws Exception {
		Method setItemMethod = Inventario.class.getMethod("setItem", Item.class);
		
		Inventario inventarioObj = new Inventario();
		Item itemObj = new Item();
		
		setItemMethod.invoke(inventarioObj, itemObj);
	}
}

class Inventario {
	public void setItem(Item item) {
		System.out.println("setItem invocado com sucesso!");
	}
}

class Item {
}

erdanielli, obrigado pela colaboração, mas meio que o que você fez foi o que fiz Oo.
Será que o problema está na hora de especificar o parâmetro?
Lá em cima no código, está:

item it = new item();

Portanto, meu parâmetro é uma instancia da classe item certo?
A função no objeto inventário é:

public void setItem(item i){
}

Por isso, devo passar como parâmetro um objeto do tipo item, mas, continua dando o erro, baseando no erro, parece que ele ta achando que it não é uma instancia de item, mas é :(.
Alguma outra luz?

Que tal vc publicar, na integra, a classe Inventario e Item ?

Talvez essa classe pai não seja uma instancia que tenha esse método

Tipo, eu sinceramente não gostaria de postar o código todo, porque é simplesmente enorme, mas se ajudar em algo…

Classe inventório: (eu sei que inventório não existe, mas eu não gosto de falar inventário XD)

package jogo;

import itens.equ.*;
import itens.usa.*;
import itens.out.*;
import jogo.bdItens;
import java.awt.Component;
import java.util.ArrayList;
import javax.swing.ImageIcon;

public class inventorio extends javax.swing.JInternalFrame {
    private int total = 0;
    private int capacidade = 50;    
    private slot slt = new slot();
    private ArrayList slots = new ArrayList();
    private slot alvo = null;    
    private bdItens bdi = new bdItens();
    
    public inventorio() {
        initComponents();
        iniciarSlots();
        povoarSlots();        
        iniciar();
        this.setName("inventorio");
    }
    
    private slot slotVazio(){
        Component[] it = pan_principal.getComponents();
        for (int i=0;i<50;i+=1){
            try {
                slot s = (slot)it[i];
                if (s.getItem().getId()==-1){
                    return s;
                }
            } catch (Exception e){
                System.out.println(e.getMessage());
                return null;
            }
        }
        return null;
    }
    
    public void setItem(item i){ //É esse método aqui que estou tentando invocar na classe slot...
        slot s = slotVazio();
        s.setItem(i);
        povoarSlots();
        atualizarContador(1);
    }
    
    public void atualizarContador(int q){
        total += q;
        cam_contador.setText(Integer.toString(total)+" / "+capacidade);
    }
        
    private void iniciar(){
        setItem(new pocao(bdi.pegarAt(0, 0)[0], bdi.pegarAt(0, 0)[1]));
        setItem(new arma(bdi.pegarAt(1, 0)[0], bdi.pegarAt(1, 0)[1]));
        setItem(new loot(bdi.pegarAt(2, 0)[0], bdi.pegarAt(2, 0)[1]));
    }
    
    private void iniciarSlots(){
        for (int j=0;j<5;j+=1){
            for (int i=0;i<10;i+=1){
                slot b = new slot();
                b.setFocusPainted(false);
                b.setSize(30, 30);
                b.setLocation(2+(32*i), 2+(32*j));
                b.setPai(this, 1);
                /*b.addMouseListener(new MouseAdapter() {
                    public void mousePressed(MouseEvent e) {
                        if (e.getButton()==3){
                            alvo = (slot)e.getComponent();
                            System.out.println(alvo.getItem().getTipo());
                        }
                    }
                });*/
                pan_principal.add(b);
            }
        }
        atualizarContador(0);
    }
    
    public void povoarSlots(){
        Component[] it = pan_principal.getComponents();
        for (int i=0;i<50;i+=1){
            try {
                slot s = (slot)it[i];
                if (s.getItem().getId()!=-1){
                    ImageIcon ic = new ImageIcon(getClass().getResource("/itens/imagens/"+s.getItem().getFoto()+".jpg"));
                    s.setIcon(ic);
                } else {
                    s.setIcon(null);
                }
            } catch (NullPointerException e){                
                System.out.println(e.fillInStackTrace());
            }
        }
    }
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        pan_principal = new javax.swing.JPanel();
        cam_contador = new javax.swing.JTextField();

        setClosable(true);
        setDefaultCloseOperation(javax.swing.WindowConstants.HIDE_ON_CLOSE);

        pan_principal.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        javax.swing.GroupLayout pan_principalLayout = new javax.swing.GroupLayout(pan_principal);
        pan_principal.setLayout(pan_principalLayout);
        pan_principalLayout.setHorizontalGroup(
            pan_principalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 322, Short.MAX_VALUE)
        );
        pan_principalLayout.setVerticalGroup(
            pan_principalLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 162, Short.MAX_VALUE)
        );

        cam_contador.setEditable(false);
        cam_contador.setHorizontalAlignment(javax.swing.JTextField.CENTER);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(pan_principal, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(cam_contador, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(pan_principal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(cam_contador, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        
    
    
    // Variables declaration - do not modify                     
    private javax.swing.JTextField cam_contador;
    public javax.swing.JPanel pan_principal;
    // End of variables declaration                   
    
}

Classe slot (todo slot guarda um item)

package jogo;

import itens.equ.*;
import itens.usa.pocao;
import java.awt.Container;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

class slot extends JButton {
    public item it;
    equipamentos def;
    private Container pai;
    private int tipoPai;
    
    private JPopupMenu popUs = new JPopupMenu();
    private JPopupMenu popEq = new JPopupMenu();
    private JPopupMenu popOu = new JPopupMenu();
    private JPopupMenu popDe = new JPopupMenu();
    JMenuItem jmiUsar = new JMenuItem("Usar");
    JMenuItem jmiEquipar = new JMenuItem("Equipar");
    JMenuItem jmiDesequipar = new JMenuItem("Desequipar");
    JMenuItem jmiExcluir1 = new JMenuItem("Excluír");
    JMenuItem jmiExcluir2 = new JMenuItem("Excluír");
    JMenuItem jmiExcluir3 = new JMenuItem("Excluír");
    JMenuItem jmiExcluir4 = new JMenuItem("Excluír");
    JMenuItem jmiCancelar1 = new JMenuItem("Cancelar");
    JMenuItem jmiCancelar2 = new JMenuItem("Cancelar");
    JMenuItem jmiCancelar3 = new JMenuItem("Cancelar");
    JMenuItem jmiCancelar4 = new JMenuItem("Cancelar");
    
    public slot(){        
        Map arg1 = new HashMap();
        arg1.put("id", -1);
        arg1.put("tipo", 1);
        arg1.put("nome", "");
        arg1.put("foto", "");
        arg1.put("desc", "");
        Map arg2 = new HashMap();
        arg2.put("subtipo", 0);
        arg2.put("ataque", 0);
        arg2.put("defesa", 0);
        def = new arma(arg1, arg2);
        it = def;
        //
        popUs.add(jmiUsar);
        popUs.add(jmiExcluir1);
        popUs.add(jmiCancelar1);
        //
        popEq.add(jmiEquipar);
        popEq.add(jmiExcluir2);
        popEq.add(jmiCancelar2);
        //
        popOu.add(jmiExcluir3);
        popOu.add(jmiCancelar3);
        //
        popDe.add(jmiDesequipar);
        popDe.add(jmiCancelar4);
        
    }
    
    public void setPai(Container c, int t){
        this.pai = c;
        this.tipoPai = t;
    }
    
    public void setItem(item i){
        this.it = i;
        switch (this.it.getTipo()) {
            case (0):
                jmiUsar.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){
                            ((pocao)it).usar();
                        }
                    }                
                });
                jmiExcluir1.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){
                            setItem(def);
                            try {
                                Class cls = Class.forName("jogo.inventorio");
                                Method mtd1 = cls.getMethod("povoarSlots", null);
                                Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE);
                                Object obj1 = mtd1.invoke(pai, null);
                                Object obj2 = mtd2.invoke(pai, -1);
                            } catch (ClassNotFoundException ee){
                                System.out.println("e0"+ee.getMessage());
                            } catch (NoSuchMethodException ee){
                                System.out.println("e1"+ee.getMessage());
                            } catch (IllegalAccessException ee){
                                System.out.println("e2"+ee.getMessage());
                            } catch (IllegalArgumentException ee){
                                System.out.println("e3"+ee.getMessage());
                            } catch (InvocationTargetException ee){
                                System.out.println("e4"+ee.getMessage());
                            }
                            setToolTipText(null);
                            setComponentPopupMenu(null);
                        }
                    }
                });
                setToolTipText(it.getInfo());
                setComponentPopupMenu(popUs);
                break;
            case (1):
                jmiEquipar.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){                            
                            switch (((arma)it).getSubTipo()){
                                case (0):
                                    ((arma)it).equipar();
                                    break;
                                default:
                                    break;
                            }
                        }
                    }                
                });
                jmiDesequipar.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){                            
                            try {
                                Class cls = Class.forName("jogo.inventorio");  //Aqui que começa o problema... Basicamente quero chamar o método setItem dentro de inventorio, sem precisar instanciar a classe inventório aki.
                                Method mtd1 = cls.getMethod("setItem", item.class);
                                Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE);
                                Object obj1 = mtd1.invoke(pai, it);
                                Object obj2 = mtd2.invoke(pai, 1);
                            } catch (ClassNotFoundException ee){
                                System.out.println("e0"+ee.getMessage());
                            } catch (NoSuchMethodException ee){
                                System.out.println("e1"+ee.getMessage());
                            } catch (IllegalAccessException ee){
                                System.out.println("e2"+ee.getMessage());
                            } catch (IllegalArgumentException ee){
                                System.out.println("e3"+ee.getMessage());
                            } catch (InvocationTargetException ee){
                                System.out.println("e4"+ee.getMessage());
                            }
                        }
                    }                
                });
                jmiExcluir2.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){
                            setItem(def);
                            try {
                                Class cls = Class.forName("jogo.inventorio");
                                Method mtd1 = cls.getMethod("povoarSlots", null);
                                Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE);
                                Object obj1 = mtd1.invoke(pai, null);
                                Object obj2 = mtd2.invoke(pai, -1);
                            } catch (ClassNotFoundException ee){
                                System.out.println("e0"+ee.getMessage());
                            } catch (NoSuchMethodException ee){
                                System.out.println("e1"+ee.getMessage());
                            } catch (IllegalAccessException ee){
                                System.out.println("e2"+ee.getMessage());
                            } catch (IllegalArgumentException ee){
                                System.out.println("e3"+ee.getMessage());
                            } catch (InvocationTargetException ee){
                                System.out.println("e4"+ee.getMessage());
                            }
                            setToolTipText(null);
                            setComponentPopupMenu(null);
                        }
                    }
                });
                setToolTipText(it.getInfo());
                if (this.tipoPai == 0){
                    setComponentPopupMenu(popDe);
                } else {
                    setComponentPopupMenu(popEq);
                }
                break;
            case (2):
                jmiExcluir3.addMouseListener(new MouseAdapter(){
                    public void mouseReleased(MouseEvent e) {
                        if (e.getButton()==1){
                            setItem(def);
                            try {
                                Class cls = Class.forName("jogo.inventorio");
                                Method mtd1 = cls.getMethod("povoarSlots", null);
                                Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE);
                                Object obj1 = mtd1.invoke(pai, null);
                                Object obj2 = mtd2.invoke(pai, -1);
                            } catch (ClassNotFoundException ee){
                                System.out.println("e0"+ee.getMessage());
                            } catch (NoSuchMethodException ee){
                                System.out.println("e1"+ee.getMessage());
                            } catch (IllegalAccessException ee){
                                System.out.println("e2"+ee.getMessage());
                            } catch (IllegalArgumentException ee){
                                System.out.println("e3"+ee.getMessage());
                            } catch (InvocationTargetException ee){
                                System.out.println("e4"+ee.getMessage());
                            }
                            setToolTipText(null);
                            setComponentPopupMenu(null);
                        }
                    }
                });
                setToolTipText(it.getInfo());
                setComponentPopupMenu(popOu);
                break;
            default:
                setToolTipText(null);
                setComponentPopupMenu(null);
                break;
        }
    }
    
    public item getItem(){
        return it;
    }
}

A classe item eu não acho necessidade de publicar, até porque ela é meio dependente… Eu fiz uma estrutura assim:
arma herda de equipamentos que herda de item: pra que simplesmente toda arma seja considerada um item.
pocao herda de usaveis que herda de item: idem cima.
chave herda de outros que herda de item: idem cima.
Basicamente eu criei uma classe pra cada tipo genérico de item, herdadando de classes mais genéricas tb.

Bem, estou no aguardo :).

Pra fechar de vez, mande o código completo do método que está fazendo a invocação por reflexão. A dúvida que resta é quem é essa variável ‘pai’ ?

Bem eduardo, a variável pai, guarda quem é o Parent, do slot, no sistema que faço, tem vários slots dentro de um Panel, no caso o Parent de cada slot seria uma instancia de Inventório.
Quanto a primeira parte da sua mensagem, eu não entendi muito bem. O método de invocação está dentro da classe Slot, ta meio dificil de encontrar, mas eu fiz um comentário pra ajudar. Obrigado pela paciencia :/.

Cara sinceramente… achei seu código complicado de entender… primeiro por que voce nao usa as convenções de código… segundo é aquela vomitada que o netbeans jogou ali para criar um JFrame… e terceiro por que voce misturou muito o que um objeto tem que fazer… o seu inventario por exemplo gerencia slots e monta a GUI… o slot já é um JButton mas ao mesmo tempo guarda um objeto item…

Não acha que seja uma boa hora para refatorar antes?

[quote=Liberokain]Bem, não sei como explicar bem, mas seria algo do tipo assim:

Class cls = Class.forName("jogo.inventorio"); //ate aki tudo bem, é onde estão os metodos que vo invocar....
Method mtd1 = cls.getMethod("setItem", item.class); //Aqui eu não se está certo, pois o parâmetro desse metodo é do tipo item...
Method mtd2 = cls.getMethod("atualizarContador", Integer.TYPE); //Aqui é um parâmetro do tipo Integer. ok.
Object obj1 = mtd1.invoke(pai, it); //Aqui provavelmente é a causa do problema. Informando que não coloquei aqui, mas já instanciei o "it" como tipo, item.
Object obj2 = mtd2.invoke(pai, 1); //Aqui vai tudo bem...

[/quote]Cara, o erro tá estampado. ‘pai’ não é do tipo ‘jogo.inventorio’. Para vc ter certeza disso, nem precisa de reflexão. Tente assim:[code]
// Vai falhar aqui!
jogo.inventorio inventorio = (jogo.inventorio) pai;

inventario.setItem(it);
inventario.atualizarContador(1);
[/code]
As dicas do colega Mark_Ameba são válidas. Esse código está péssimo (nada pessoal :slight_smile: ) e precisa de um refactor radical!

Eduardo, só pude entrar hoje para ver sua resposta, e antes de entrar já tava corrigindo o problema, pois me esforçando consegui constatar o erro atraves dos detalhes do try-catch, foi complicado adaptar o código pra fazer o que estava querendo pra não dar mais o erro.
Quanto a organização. A “sujeira” que o netbeans coloca, acho que para quem já é familiarizado com java, consegue separar claramente, e a organização e clareza só não estão sendo vistas, pois além de não estar expostas todas as classes, não comentei. Me garanto com meu código.

Obrigado pela paciência e qualquer coisa se puder ajudar, tamo ai :D.

Não é só por que ta sem os comentários que esta dificil de entender… Estou dizendo por questões de OO mesmo… um objeto slot extends JButton que tem um item e o equipamento… não me vejo um cenario onde um botão teria um item e um equipamento… acho que ele deveria apenas chamar ações.

Fora que não usar os padrões de escrita de código complica os outros entenderem o que voce escreveu do seu jeito.