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…
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”.
RenataFA
everson_z:
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?!?
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… :?
Ainda bem que vc não entendeu… 8)
RenataFA
thingol:
Vamos lá.
Digamos que você tenha a seguinte classe derivada de JFrame:
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”.
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!
T
thingol
Que peninha é modo de dizer. Vou dar um exemplo simples:
importjava.awt.*;importjavax.swing.*;importjava.lang.reflect.*;classUtil{// 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.publicstaticvoidatribuirNomes(Containercontainer){Class<?>containerClass=container.getClass();Field[]fields=containerClass.getDeclaredFields();if(fields==null)return;for(Fieldfield:fields){Objectobj=null;try{field.setAccessible(true);obj=field.get(container);}catch(IllegalAccessExceptionex){ex.printStackTrace();}if(obj!=null&&Component.class.isAssignableFrom(obj.getClass())){// Neste caso, devemos chamar setName:((Component)obj).setName(field.getName());}}}}classTesteNomesComponentesextendsJFrame{privateJLabeljlLabel1=newJLabel("Passe o cursor para ver um tooltip");privateJLabeljlLabel2=newJLabel("com o nome deste componente");privateJButtonjbButton1=newJButton("Botão 1");privatevoidinitComponents(){setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(0,0,300,100);add(jlLabel1,BorderLayout.NORTH);add(jlLabel2,BorderLayout.CENTER);add(jbButton1,BorderLayout.SOUTH);}publicTesteNomesComponentes(){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());}publicstaticvoidmain(String[]args){TesteNomesComponentestnc=newTesteNomesComponentes();tnc.setVisible(true);}}
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
jjose
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
T
thingol
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
É isso aí mesmo, dona Renata, mas como você deve ter entendido, você sempre pode dar um jeito (como é o caso do que escrevi acima).
RenataFA
thingol:
É 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... :(
Bom, aceito sugestões! :wink:
importjava.awt.BorderLayout;importjava.awt.Component;importjava.awt.Container;importjava.lang.reflect.Field;importjavax.swing.JButton;importjavax.swing.JFrame;importjavax.swing.JLabel;classTesteNomesComponentesextendsJFrame{privateJLabeljlLabel1;privateJLabeljlLabel2;privateJButtonjbButton1;privatevoidinitComponents(){jlLabel1=newJLabel("Passe o cursor para ver um tooltip");jlLabel2=newJLabel("com o nome deste componente");jbButton1=newJButton("Botão 1");setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);setBounds(0,0,300,100);jbButton1.addActionListener(newjava.awt.event.ActionListener(){publicvoidactionPerformed(java.awt.event.ActionEventevt){clicouBotao(evt);}});add(jlLabel1,BorderLayout.NORTH);add(jlLabel2,BorderLayout.CENTER);add(jbButton1,BorderLayout.SOUTH);}publicTesteNomesComponentes(){super("Teste de Nomes de Componentes");initComponents();}publicstaticvoidmain(String[]args){TesteNomesComponentestnc=newTesteNomesComponentes();tnc.setVisible(true);}privatevoidclicouBotao(java.awt.event.ActionEventevt){if(evt.getSource()==jbButton1){jbButton1.setText(pegaNome(this,jbButton1));}}privateStringpegaNome(Containercontainer,Componentcomp){Stringretorno="";Class<?>containerClass=container.getClass();Field[]fields=containerClass.getDeclaredFields();if(fields.length>0){for(Fieldf:fields){Objectobj=null;try{f.setAccessible(true);obj=f.get(container);}catch(IllegalAccessExceptionex){ex.printStackTrace();}if((obj!=null)&&((Component)obj==comp)){// achei o componente que estou procurandoif(Component.class.isAssignableFrom(obj.getClass()))retorno=f.getName();// pego o nomebreak;// paro o loop}}}returnretorno;}}
T
thingol
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.).
RenataFA
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:
everson_z
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?!?
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…