[RESOLVIDO] Variable name

Bom dia!

Eu sei a diferença entre variable name e name de um Component.
É óbvio que não se pode (nem se deve!!!) modificar o conteúdo da variable name durante a execução.

Mas por favor me digam, não tem nenhuma forma de eu pegar o valor da variable name em tempo de execução?

Já pesquisei, e nada! Todo lugar fala pra preencher o atributo name e usar ele… :cry:

Alguma luz?! :idea:

Grata

Pera ai, ficou meio confuso…

Seu variable name é o identificador e o name é o atributo do Component?
Vc quer saber o nome do identificador, é isso?

[quote=davidbuzatto]Pera ai, ficou meio confuso…

Seu variable name é o identificador e o name é o atributo do Component?
Vc quer saber o nome do identificador, é isso?[/quote]

Amigo, essa explicação do thingol responde sua dúvida com respeito a diferença entre eles: http://www.guj.com.br/posts/list/32590.java

E sim! Quero pegar o nome do identificador.

Eu sei o que é o name do Component, só achei que a forma q vc expôs a dúvida ficou confusa.

Quando a sua dúvida, vc já usou reflexão?

Reflection te dá várias informações de uma classe, entre elas nomes de métodos e nomes de variaveis membro.

Ok, me desculpe se fui confusa. Mas vamos deixar a confusão de lado. Alguma idéia?

Sobre o Reflection, eu costumo usar Reflection, mas isso ai eu não sei fazer.

Eu sei pegar um método, ou um componente, ou uma variável, mas tudo eu pego tendo o nome do que eu quero pegar.

O que eu preciso é o contrário, eu tenho o componente, mas não tenho o nome. Alguém me explica como faço isso usando Reflection?!?

Vamos lá.

Digamos que você tenha a seguinte classe derivada de JFrame:

class MeuJFrame extends JFrame {
    private JLabel meuLabel = new JLabel ("abobora");
    private JPanel meuPanel = new JPanel();
    public MeuJFrame () {
        super ("exemplo");
        meuLabel.setName ("rotulo");
        add (meuLabel);
        add (meuPanel);
        JSpinner meuSpinner = new JSpinner();
        add (meuSpinner);
    }
}

Como você sabe:

  • Variáveis têm nomes, mas objetos não têm nomes. Isso porque um mesmo objeto pode ser referenciado por mais de uma variável.

  • Os nomes das variáveis de instância você consegue pegar via reflection. Dá trabalho mas é possível. Entretanto, dado apenas o valor da variável da instância (o objeto) você não consegue pegar o tal nome, porque o objeto não tem uma referência “de volta”.*

  • Os nomes das variáveis locais não dá para pegar nem via reflection. Eles são perdidos. (A rigor, se o programa for compilado com informação de debug, é possível, com muito trabalho, obter os nomes das variáveis locais).

  • Você consegue pegar o atributo “name” de um JComponent com getName() se você atribuí-lo com setName() (digamos durante a construção).

  • A rigor, nesse caso em particular você pode até determinar qual é o parent se você adicionar o componente ao JFrame, mas é por dedução e nem sempre é algo que funciona corretamente. Por isso, simplificando, eu digo que o objeto em si “não tem nome”.

[quote=everson_z][quote=RenataFA]Ok, me desculpe se fui confusa. Mas vamos deixar a confusão de lado. Alguma idéia?

Sobre o Reflection, eu costumo usar Reflection, mas isso ai eu não sei fazer.

Eu sei pegar um método, ou um componente, ou uma variável, mas tudo eu pego tendo o nome do que eu quero pegar.

O que eu preciso é o contrário, eu tenho o componente, mas não tenho o nome. Alguém me explica como faço isso usando Reflection?!?[/quote]

O Que? Em português,
What? Em Inglês,
Was? Em Alemão,
Quoi? Em Francês,
Τι; Em Grego,
Cosa? Em Italiano,
什么?Em Chinês…

Agora, entender o que você pediu… :?
[/quote]

Ainda bem que vc não entendeu… 8)

[quote=thingol]Vamos lá.

Digamos que você tenha a seguinte classe derivada de JFrame:

class MeuJFrame extends JFrame {
    private JLabel meuLabel = new JLabel ("abobora");
    private JPanel meuPanel = new JPanel();
    public MeuJFrame () {
        super ("exemplo");
        meuLabel.setName ("rotulo");
        add (meuLabel);
        add (meuPanel);
        JSpinner meuSpinner = new JSpinner();
        add (meuSpinner);
    }
}

Como você sabe:

  • Variáveis têm nomes, mas objetos não têm nomes. Isso porque um mesmo objeto pode ser referenciado por mais de uma variável.

  • Os nomes das variáveis de instância você consegue pegar via reflection. Dá trabalho mas é possível. Entretanto, dado apenas o valor da variável da instância (o objeto) você não consegue pegar o tal nome, porque o objeto não tem uma referência “de volta”.*

  • Os nomes das variáveis locais não dá para pegar nem via reflection. Eles são perdidos. (A rigor, se o programa for compilado com informação de debug, é possível, com muito trabalho, obter os nomes das variáveis locais).

  • Você consegue pegar o atributo “name” de um JComponent com getName() se você atribuí-lo com setName() (digamos durante a construção).

  • A rigor, nesse caso em particular você pode até determinar qual é o parent se você adicionar o componente ao JFrame, mas é por dedução e nem sempre é algo que funciona corretamente. Por isso, simplificando, eu digo que o objeto em si “não tem nome”. [/quote]

Certo thingol, entendi… então é bem o caso que vc mencionou msm, podemos dizer que meu objeto “não tem nome”, pq eu não tenho como pegar o tal nome… Que peninha!!!

Mas blz, vlw! :wink:

Que peninha é modo de dizer. Vou dar um exemplo simples:

import java.awt.*;
import javax.swing.*;
import java.lang.reflect.*;

class Util {
    // Varre cada variável de instância do objeto, e vê se é um Component. Se for,
    // então seta a propriedade "name" do objeto associado a essa variável.
    public static void atribuirNomes (Container container) {
        Class<?> containerClass = container.getClass();
        Field[] fields = containerClass.getDeclaredFields ();
        if (fields == null) return;
        for (Field field : fields) {
            Object obj = null;
            try {
                field.setAccessible (true);
                obj = field.get (container); 
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            }
            if (obj != null && Component.class.isAssignableFrom (obj.getClass())) {
                // Neste caso, devemos chamar setName:
                ((Component) obj).setName (field.getName());
            }
        }
    }
}

class TesteNomesComponentes extends JFrame {
    private JLabel jlLabel1 = new JLabel ("Passe o cursor para ver um tooltip");
    private JLabel jlLabel2 = new JLabel ("com o nome deste componente");
    private JButton jbButton1 = new JButton ("Botão 1");
    private void initComponents() {
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setBounds (0, 0, 300, 100);
        add (jlLabel1, BorderLayout.NORTH);
        add (jlLabel2, BorderLayout.CENTER);
        add (jbButton1, BorderLayout.SOUTH);
    }
    public TesteNomesComponentes() {
        super ("Teste de Nomes de Componentes");
        initComponents();
        Util.atribuirNomes (this); // isto atribui ao atributo "name" o nome da variável.
        // Só para brincar, vamos setar um tooltip para cada JComponent deste JFrame
        // com o valor de getName.
        jlLabel1.setToolTipText (jlLabel1.getName());
        jlLabel2.setToolTipText (jlLabel2.getName());
        jbButton1.setToolTipText (jbButton1.getName());
    }
    public static void main(String[] args) {
        TesteNomesComponentes tnc = new TesteNomesComponentes();
        tnc.setVisible (true);
    }
}

Lindo isso ai thingol!!!

Não resolve meu probleminha mas gostei muito de aprender isso!

No meu caso, pra resumir, digamos q tenho um método que recebe um Component (para que possa receber diversos objetos).
Gostaria de a partir desse Component pegar o nome dele (bem, não o atributo name, mas o variable name, vc deve ter entendido).

Mas pelo que vc me explicou, não tem jeito de fazer oque quero pq o Component que recebo no meu método é só uma referência para o Object declarado na minha classe. Certo? Ou viajei?

Grata :wink:

Re
acho que ninguem entendeu o que vc realmente precisa :oops:
eu entendi que tu sabe o que eh
como faz
mas naum o que que
pode mandar pm que sempre q possivel t respondo

[quote=RenataFA]Lindo isso ai thingol!!!

Não resolve meu probleminha mas gostei muito de aprender isso!

No meu caso, pra resumir, digamos q tenho um método que recebe um Component (para que possa receber diversos objetos).
Gostaria de a partir desse Component pegar o nome dele (bem, não o atributo name, mas o variable name, vc deve ter entendido).

Mas pelo que vc me explicou, não tem jeito de fazer oque quero pq o Component que recebo no meu método é só uma referência para o Object declarado na minha classe. Certo? Ou viajei?

Grata :wink: [/quote]

É isso aí mesmo, dona Renata, mas como você deve ter entendido, você sempre pode dar um jeito (como é o caso do que escrevi acima).

Então thingol, seguindo sua idéia, eu fiz um esquema aqui que funciona como preciso, ou seja, passo o Component e ele me dá o nome com o qual ele foi declarado. Vou postar o código aqui, me ajude com dicas pra melhorar a performace, penso que funciona mas quando se tratar de uma classe que tem muitos objetos vai ficar lento… :frowning:

Bom, aceito sugestões! :wink:

[code]import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.lang.reflect.Field;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

class TesteNomesComponentes extends JFrame {
private JLabel jlLabel1;
private JLabel jlLabel2;
private JButton jbButton1;

private void initComponents() {
	
    jlLabel1 = new JLabel ("Passe o cursor para ver um tooltip");
    jlLabel2 = new JLabel ("com o nome deste componente");
    jbButton1 = new JButton ("Botão 1");
	
    setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    setBounds (0, 0, 300, 100);
    
    jbButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            clicouBotao(evt);
        }
    });
    
    add (jlLabel1, BorderLayout.NORTH);
    add (jlLabel2, BorderLayout.CENTER);
    add (jbButton1, BorderLayout.SOUTH);
}
public TesteNomesComponentes() {
    super ("Teste de Nomes de Componentes");
    initComponents();
}

public static void main(String[] args) {
    TesteNomesComponentes tnc = new TesteNomesComponentes();
    tnc.setVisible (true);
}

private void clicouBotao(java.awt.event.ActionEvent evt){
	if (evt.getSource() == jbButton1){
		jbButton1.setText(pegaNome(this,jbButton1));
	}

}

private String pegaNome(Container container, Component comp){
	String retorno = "";
	
    Class<?> containerClass = container.getClass();
    Field[] fields = containerClass.getDeclaredFields();
    if (fields.length > 0){
    	for (Field f : fields){
    		Object obj = null;
    		
            try {
                f.setAccessible(true);
                obj = f.get(container); 
            } catch (IllegalAccessException ex) {
                ex.printStackTrace();
            }
            
            if ((obj != null) && ((Component)obj == comp)){ // achei o componente que estou procurando
                if (Component.class.isAssignableFrom (obj.getClass())) 
                	retorno = f.getName(); // pego o nome
                break; // paro o loop
            }
    	}
    }
	
	return retorno;
}

}
[/code]

Você pode fazer um “cache” dos nomes desses objetos, para que isso não fique muito lento. Mas acho que para uma tela com menos de 100 componentes nem precisa fazer algo muito complicado (talvez você possa fazer como eu fiz, ou seja, atribuir os nomes aos componentes com setName, tal como sugerido, e fazer isso apenas quando necessário. Se o componente já estiver com a propriedada “name” setada, nem precisa recalcular o nome dele novamente.).

Bom, dei até uma modificada nela aqui pra que receba apenas o Component como parâmetro e faça o resto.

Está muito bom pro que eu preciso (que tb não será toda hora que terei que acessar esse método).

Obrigada pela ajuda de todos, especialmente a do thingol.

Vlw!! :lol:

[quote=RenataFA]Ok, me desculpe se fui confusa. Mas vamos deixar a confusão de lado. Alguma idéia?

Sobre o Reflection, eu costumo usar Reflection, mas isso ai eu não sei fazer.

Eu sei pegar um método, ou um componente, ou uma variável, mas tudo eu pego tendo o nome do que eu quero pegar.

O que eu preciso é o contrário, eu tenho o componente, mas não tenho o nome. Alguém me explica como faço isso usando Reflection?!?[/quote]

O Que? Em português,
What? Em Inglês,
Was? Em Alemão,
Quoi? Em Francês,
Τι; Em Grego,
Cosa? Em Italiano,
什么?Em Chinês…

Agora, entender o que você pediu… :?