[RESOLVIDO]For para armazenar vários botões em uma lista de JButtons

32 respostas
L

Galera é o seguinte eu tenho vários JButtons( coloquei apenas os nomes ali, mas no meu código eles estão instanciados ):

botao0;
botao1;
botao2;
...
botao9;

Eu estou usando o NetBeans, se eu não tivesse acho que já teria conseguido, acho que não consegui pelo maldito método initComponents() que não edita¬¬. Mas vejamos agora eu tenho um método que eu armazeno todos esse botões em um array de JButtons assim:

private void armazenaBotoesN() {
        botoesN[0] = botao0;
        botoesN[1] = botao1;
        botoesN[2] = botao2;
        botoesN[3] = botao3;
        botoesN[4] = botao4;
        botoesN[5] = botao5;
        botoesN[6] = botao6;
        botoesN[7] = botao7;
        botoesN[8] = botao8;
        botoesN[9] = botao9;
}

Eu queria saber se tem uma forma melhor de se fazer isso porque com for usando String não tem como, nem usando Cast de JButton para uma string tem, tipo assim:

for( int i = 0; i <10; i++ ) {
        botoesN[i] = (JButton) "botao" + i;
}

Issp não é possível, gostaria de saber se tem alguma forma de fazer mais ou menos assim para eu economizar linhas de código.

32 Respostas

E

A resposta simples é “continue a fazer com aquele código que você escreveu”. Como já falei duzentas vezes aqui no fórum:

a) Cast não é conversão (exceto no caso de tipos primitivos, e tanto String quando JButton não são tipos primitivos)
b) Você pode tentar fazer as coisas via reflection mas acho que não vale a pena
c) O correto, no seu caso, talvez fosse fazer as coisas de trás para frente (ou seja, em vez de criar os botões usando o editor gráfico do Netbeans, criá-los via código).

L

entanglement:
A resposta simples é “continue a fazer com aquele código que você escreveu”. Como já falei duzentas vezes aqui no fórum:

a) Cast não é conversão (exceto no caso de tipos primitivos, e tanto String quando JButton não são tipos primitivos)
b) Você pode tentar fazer as coisas via reflection mas acho que não vale a pena
c) O correto, no seu caso, talvez fosse fazer as coisas de trás para frente (ou seja, em vez de criar os botões usando o editor gráfico do Netbeans, criá-los via código).

Pois é, criando via código eu acho que talvez daria, na hora das instâncias dos JButtons, mas estou tentando saber se tem como fazer isso depois de ter instanciado.

J

Não vejo mal algum em usar o método preenchido com os botões e cria-los pelo

for( int i = 0; i <10; i++ ) { botoesN[i] = (JButton) "botao" + i; }

Como o amigo acima falou, se queres se livrar disso, faça os botoões “na mão” e adicione-os com o for

L

JuniorMaia:
Não vejo mal algum em usar o método preenchido com os botões e cria-los pelo

for( int i = 0; i <10; i++ ) { botoesN[i] = (JButton) "botao" + i; }

Como o amigo acima falou, se queres se livrar disso, faça os botoões “na mão” e adicione-os com o for

Como assim não ve mal algum? Simplesmente esse for não funciona. Tirando a parte que você falou para eu fazer na mão, não entendi o resto que você disse.

J

então lucas_guj, eu não disse que o for esta ou não funcionando, apenas mencionei que a possibilidade de fazer assim, não vejo problema, mas se tu não quer usar métodos e for para criar os botões, terá que fazer na mão… entendeu?

L

Agora entendi. Mas na verdade eu QUERO usar for para ARMAZENAR os botões no array, só que não sei como.

E

Eu não tenho o NetBeans aqui para poder verificar qual é o estilo de criação dos botões.

Digamos que os botões tenham o seguinte nome (você foi esperto suficiente para não aceitar aquele nome tosco que o Netbeans lhe dá por default, não? )

btnNome001, btnNome002, btnNome003 … btnNome010.

Para você puxar os botões via reflection, você poderia fazer algo como:

for (int i = 1; i <= 10; i++) { 
         try {
             botoes[i] = (JButton) this.getClass().getField (String.format ("btnNome%03d", i)).get(this);
         } catch (........) {// complete aqui com os catches adequados, usar getField e get são operações que geram um monte de exceções diferentes
         } catch (........) {
         } catch (........) {
         } catch (........) {
         } catch (........) {
         }
     }

Mas acho que não vale a pena, pois:
a) é muito mais lento que aquele código que você pôs
b) você não economiza nenhuma linha, na verdade você acaba gastando mais linhas
c) se você precisar botar mais um botão, você vai ter de modificar esse método de qualquer maneira.
d) Sem contar que você não pode fugir dessa nomenclatura para o código funcionar direito.

F

Vc leu oq o entanglement disse?
Cast apenas para valores primitivos. (int, char . . .);

O que vc pode fazer é intanciar e já guardar no array. Mas creio que isso vai te dar trabalho no futuro…

for (i = 0; i < 10; i++) {
  btn[i] = new JButton("botao" + i);
}
L

entanglement:
Eu não tenho o NetBeans aqui para poder verificar qual é o estilo de criação dos botões.

Digamos que os botões tenham o seguinte nome (você foi esperto suficiente para não aceitar aquele nome tosco que o Netbeans lhe dá por default, não? )

btnNome001, btnNome002, btnNome003 … btnNome010.

Para você puxar os botões via reflection, você poderia fazer algo como:

for (int i = 1; i <= 10; i++) { 
         try {
             botoes[i] = (JButton) this.getClass().getField (String.format ("btnNome%03d", i)).get(this);
         } catch (........) {// complete aqui com os catches adequados, usar getField e get são operações que geram um monte de exceções diferentes
         } catch (........) {
         } catch (........) {
         } catch (........) {
         } catch (........) {
         }
     }

Mas acho que não vale a pena, pois:
a) é muito mais lento que aquele código que você pôs
b) você não economiza nenhuma linha, na verdade você acaba gastando mais linhas
c) se você precisar botar mais um botão, você vai ter de modificar esse método de qualquer maneira.
d) Sem contar que você não pode fugir dessa nomenclatura para o código funcionar direito.

Claro que não acc aqueles nomes. Eu mudei os nomes, como coloquei no post. O nome de cada botao é: botao1, botao2 e assim até botão9.

Nesse exemplo que você deu acho que não seria tão ruim quando eu tivesse certeza de que não acrescentaria nenhum botão a mais( tipo no caso de botões numéricos de 0 a 9 ) e porque ele vai ser mais lento do que ir adicionando linha por linha? Mais fazendo por esse exemplo ao mesmo tempo como você disse em relação a gastar menos linhas é verdade, na realidade vou usar até mais linhas e não compensa de qualquer jeito, fora que vou ter que ficar tratando com exceções quando posso fazer sem tratar¬¬ Realmente vou fazer do jeito que estava mesmo um por um. Obrigado

E
botoes[i] = (JButton) this.getClass().getField (String.format ("btnNome%03d", i)).get(this);
Esta coisa monstruosa faz o seguinte (supondo que este código seja chamado na própria classe contendo os botões).

a) Pega o objeto java.lang.Class relacionado com o objeto desta classe (ou seja, this.getClass())

b) Chama o método getField(), que retorna um java.lang.reflect.Field, que é um objeto especial que representa um campo de uma classe

c) O parâmetro para getField é o nome do campo (que montei usando String.format)

d) Então, peguei o objeto java.lang.reflect.Field, e para pegar o valor que está nesse campo, usei o método get, que requer um objeto da classe que quero inspecionar.

Viu como é trabalhoso explicar tudo? A JVM também faz um certo trabalho para pegar tudo isso.

L

entanglement:
botoes[i] = (JButton) this.getClass().getField (String.format ("btnNome%03d", i)).get(this);

Esta coisa monstruosa faz o seguinte (supondo que este código seja chamado na própria classe contendo os botões).

a) Pega o objeto java.lang.Class relacionado com o objeto desta classe (ou seja, this.getClass())

b) Chama o método getField(), que retorna um java.lang.reflect.Field, que é um objeto especial que representa um campo de uma classe

c) O parâmetro para getField é o nome do campo (que montei usando String.format)

d) Então, peguei o objeto java.lang.reflect.Field, e para pegar o valor que está nesse campo, usei o método get, que requer um objeto da classe que quero inspecionar.

Viu como é trabalhoso explicar tudo? A JVM também faz um certo trabalho para pegar tudo isso.

Percebi. Mas fácil como eu estava fazendo mesmo.

I

Pergunta: Serão apenas estes 9 botões :?:

Se sim, nem vale a pena fazer vetor de botões.

Eu já precisei de 100 botões em uma tela (eu era iniciante e fazia POG), não aconselho :thumbdown: , mas funciona assim:

for (byte i=0; i&lt;10; i++) {
      botoesN[i] = new JButton();
}

:thumbup:

L

InicianteJavaHenrique:
Pergunta: Serão apenas estes 9 botões :?:

Se sim, nem vale a pena fazer vetor de botões.

Eu já precisei de 100 botões em uma tela (eu era iniciante e fazia POG), não aconselho :thumbdown: , mas funciona assim:

for (byte i=0; i&lt;10; i++) {
      botoesN[i] = new JButton();
}

:thumbup:

Nesse array são somente 9 botões porque é o array de números, mas depois tenho o array de teclas do alfabeto e etc. Porque os meus botões são os mesmos do teclado( Não exatamente todos, mas os necessários para digitar frases, etc. )

Você usa NetBeans? Se usa, sabe como eu poderia modificar o método initComponents para inserir essa linha? Porque a inicialização dos componentes é feita lá, pelo o que eu sei, a única coisa que posso fazer é pegar um componente já criado( já colocado na interface ) e clicar com o lado direito nele e personalizar código. Agora editar o método mesmo como você está falando ai para eu colocar esse for( que foi minha ideia inicial) no método initComponents, eu não consigo. Obrigado.

I

Uso NetBeans, mas crio minhas GUI na mão :smiley:

Como você disse só é possível personalizar código de componentes inseridos, porém, você pode:

:arrow: Logo abaixo do método initComponents(); que é chamado no construtor da classe, criar seu método de inicialização e chamá-lo. :idea:

public construtorDaClasse() {
      initComponents();
      minhaInicializacao(); //neste método você faz o for de botões
}

:arrow: Abrir sua classe em um editor de texto e inserir o for de botões no initComponents(); e para que o NetBeans não bloquei mais a alteração remova aqueles comentários que ele coloca no initComponents(); :idea:

:thumbup:

L

InicianteJavaHenrique:
Uso NetBeans, mas crio minhas GUI na mão :smiley:

Como você disse só é possível personalizar código de componentes inseridos, porém, você pode:

:arrow: Logo abaixo do método initComponents(); que é chamado no construtor da classe, criar seu método de inicialização e chamá-lo. :idea:

public construtorDaClasse() {
      initComponents();
      minhaInicializacao(); //neste método você faz o for de botões
}

:arrow: Abrir sua classe em um editor de texto e inserir o for de botões no initComponents(); e para que o NetBeans não bloquei mais a alteração remova aqueles comentários que ele coloca no initComponents(); :idea:

:thumbup:

KRLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL…

Descobriu o caminho das pedras. Pelo menos para mim você fez isso. Agora eu consigo editar o método initComponents e fazer ele se curvar diante de mim. HAHAHAHAHAHAHAHAHHAHAH( Graças ao “InicianteJavaHenrique” ) :smiley:

:idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea: :idea:

Amigo o meu método initComponents vai da linha 50 até 300, ou seja, 250 linhas de código. Agora que ele ser curvou a minha vontade. Vamos ver em quantas linhas eu vou conseguir reduzir fazendo isso na mão. Fique de olho no tópico que eu vou postar daqui a pouco ou depois( que eu vou sair daqui a pouco ). Obrigado cara.

L

Porém recebi um informe quando vou para a visualização da janela, dizendo que o arquivo foi corrompido e que ele vai ser aberto somente com leitura. Mas vou tentar fazer do meu jeito e depois retornar com os comentários para ver se funciona. E respondo aqui.

I

É isso ai faça os testes e depois poste o resultado.

you winner
Netbeans loser

:thumbup:

L

InicianteJavaHenrique:
É isso ai faça os testes e depois poste o resultado.

you winner
Netbeans loser

:thumbup:

Que Shit! Pensei que tinha funcionado. Tipo eu edito do meu jeito. Coloco o comentario de volta e abro, ai ele volta como estava antes¬¬ Maldito Ditador. É acho que é melhor deixar ele configurar do jeito dele mesmo porque se eu deleto e crio um botao no mesmo lugar ou em outro ele já sabe onde inserir o código. O negócio é aprender a tentar fazer ele modificar certas coisas. Mas pelo visto não tem como =/

I

Não mexer é uma opção.

Aquela mensagem de corrompido do NetBeans só enche o saco, mas não corrompe o projeto em si.

Segue em anexo um teste, note que só basta você remover os comentários do initComponents(); e não ligar para a mensagem do NetBeans, e ir editando este método na própria IDE, ao final inserir os comentários do NetBeans de novo (se desejar) e fechar e abrir o projeto. Pronto :!:

L

InicianteJavaHenrique:
Não mexer é uma opção.

Aquela mensagem de corrompido do NetBeans só enche o saco, mas não corrompe o projeto em si.

Segue em anexo um teste, note que só basta você remover os comentários do initComponents(); e não ligar para a mensagem do NetBeans, e ir editando este método na própria IDE, ao final inserir os comentários do NetBeans de novo (se desejar) e fechar e abrir o projeto. Pronto :!:

Baixei o seu exemplo, vi que o método ficou realmente editado, porém os componentes não apareceram no frame pq? :shock:

I

Não aparecem na tela (em tempo de edição) porque a estrutura de repetição for só inicia em tempo de execução.

É por estas e outras que eu prefiro criar GUI na mão, mesmo com estes truques de “driblar” o NetBeans, você não vê nada na tela mesmo e tem que saber mentalmente onde está cada componente, ou seja, sem ajuda de visual editor.

Criar telas na mão não é difícil, só basta conhecer os gerenciadores de layout.

:thumbup:

L

InicianteJavaHenrique:
Não aparecem na tela (em tempo de edição) porque a estrutura de repetição for só inicia em tempo de execução.

É por estas e outras que eu prefiro criar GUI na mão, mesmo com estes truques de “driblar” o NetBeans, você não vê nada na tela mesmo e tem que saber mentalmente onde está cada componente, ou seja, sem ajuda de visual editor.

Criar telas na mão não é difícil, só basta conhecer os gerenciadores de layout.

:thumbup:

Realmente, esqueci desse detalhe¬¬…Sinceramente, sinceramente mesmo, as vezes acho até mais fácil criar na mão do que no visual editor. Porém o ruim é na hora de setar as propriedades( cade que eu vou lembrar de cabeça na hora ), ai vou ter que ficar caçando na API e também ter que ficar compilando e executando toda hora para ver onde estão os componentes. E que cacete, esses gerenciadores de Layout são dificeis de manejar, pelo menos por enquanto para mim. Cara, eu posso colocar para download aqui o meu projeto( na verdade um exercício do livro Java Como Programar ) para você ver por que eu usei o layout direitinho, na hora que eu estou vendo no visual editor ta tudo bonitinho, na hora que eu clico no olho do netBeans tambem a pré-visualização, mas quando inicio, fica bagunçado? Posso?

I

Sim.

Talvez eu possa ajudar, pelo menos vou tentar. :smiley:

L

:smiley:

I

Já baixei, em breve posto o resultado.

:thumbup:

L

InicianteJavaHenrique:
Já baixei, em breve posto o resultado.

:thumbup:

Ok. Tentei deixar comentário o melhor possível( Dê um desconto que eu sou iniciante :slight_smile: ) ahhh e se você conseguir entender porque o Ç não aparece na tela vai ser um milagre também, até criei um tópico para isso, mas ainda não consegui resolver meu problema. Obrigado

I

Segue em anexo :arrow: Inserir mais alguns JPanel (tem algum problema :?: ) para que os botões permaneçam no lugar certo.

P.S: Sobre ç não entendi a dúvida :wink: não aparece onde :?:

:thumbup:

L

InicianteJavaHenrique:
Segue em anexo :arrow: Inserir mais alguns JPanel (tem algum problema :?: ) para que os botões permaneçam no lugar certo.

P.S: Sobre ç não entendi a dúvida :wink: não aparece onde :?:

:thumbup:

Não tem problema não. Baixei e abri aqui. Ficou legal. Por que do jeito que eu estava fazendo não estava dando certo? Consegue me explicar? De qualquer forma, obrigado. Quanto ao problema do Ç, não precisa se preocupar que já me ajudaram e consegui resolver. Obrigado mais uma vez.

L

De 250 linhas para o método initComponents original, foi para 138 editado. O ruim de se fazer isso é que não se pode trabalhar mais com o matisse, porque se você for usar alguma coisinha qualquer que seja ali, ai o código volta ao original( só o método initComponents ). E a classe inteira de 500 linhas foi para 348. Diminiui bastante as linhas de código porém eu não vou ter mas a comodidade de usar o matisse para fazer qualquer alteração que seja. E eu pude perceber que eu gastei mais tempo fazendo na mão. Economizei código, porém, gastei mais tempo. O que você acha sobre isso?

I

Não estava dando certo porque quando você visualiza no editor (antigo matisse - atual drag and drop) o JFrame aparece sem L&F, porém na execução do programa o L&F é setado e gera pequenas alterações no tamanho e formato dos componentes, assim, em um todo o gerenciador de layout distribui os componentes de maneira mais adequada na tela.

:thumbup:

I

Já tive bastante dúvidas sobre isto, inclusive até um tópico (há mais de 1 ano) :arrow: http://www.guj.com.br/java/235620-aos-que-trabalham-com-java-resolvido

Porém, sigo minha conclusão da época:

Sobre a questão de tempo de produção, é só com prática.

Note que: o que te deixa mais a vontade para produzir é o certo. Não se preocupe com isto.

:thumbup:

L

Muito obrigado pelas respostas e agradeço mais uma vez por tudo. Muito obrigado mesmo. Consegui entender. Abraços.

Criado 16 de maio de 2012
Ultima resposta 19 de mai. de 2012
Respostas 32
Participantes 5