Criando e Instanciando vários Objetos em Tempo de execução

5 respostas
Yelden

Olá!
Estou precisando de uma mãozinha, estou enrolado em um problema,

Estou fazendo uma interface que consiste em um panel criando vários JButtons, um para cada dado extraído do banco.
O problema é: os dados do banco variam! e por isso, o número de JButtons também varia...

Fiz um for da seguinte maneira:

for (Programa i : programas){
				
				
				
				btnPrograma = new JButton(i.getNome());
				btnPrograma.setIcon(new ImageIcon(Inicial2.class.getResource("/Icones/1393395397_document.png")));
				btnPrograma.setVerticalTextPosition(SwingConstants.BOTTOM); 
				btnPrograma.setHorizontalTextPosition(SwingConstants.CENTER);
				btnPrograma.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
				btnPrograma.setBorderPainted(false);
				btnPrograma.setContentAreaFilled(false);
				btnPrograma.setBounds(60, 382, 62, 50);
				btnPrograma.addActionListener(this);
				
				btnPrograma.setVisible(true);
				btnPrograma.setBorder(null);
				//labelnome.addFocusListener((FocusListener) this);
				panel.add(btnPrograma, gbc_labelnome);
				
				
				
}//Fim for

Onde programas é uma lista com os programas retirados do Banco, sendo assim, ele cria um JButton para cada programa do banco e coloca no panel em forma de flowlayout.
Isso até funciona, mas o problema, é que eu perco o controle dos objetos, e quando vou usar o Listener, ele só consegue captar o último botão inserido, pois como todos botões receberam o nome de btnPrograma, apenas o último responde por esse nome. (Um substituiu o outro).

Minha idéia é mudar o nome dos botões conforme eles vão sendo criados, porém, não tem como atribuir o nome a uma variavel na hora de criar o objeto.

Pesquisei então sobre Java Reflection, e já quebrei a cabeça e não consegui entender, a maioria dos exemplos é sobre usar os métodos de uma classe... nenhum fala sobre instanciação (ou são pouquíssimos claros).

Agradeço a quem puder ajudar.

5 Respostas

pmlm

Provavelmente o teu problema resolve-se de forma muito mais simples do que com reflection, usando um Map de botões.

Map<String,JButton> botoes = new HashMap<String,JButton>();
for (Programa i : programas){  
      btnPrograma = new JButton(i.getNome());  
      (...)
      botoes.put(i.getNome(), btnPrograma); // assumindo que i.getNome() devolve um nome único para cada programa
}
(...)
botoes.get("NOME_DO_BOTAO").fazQQcoisa()... //substituindo NOME_DO_BOTAO pelo nome dado anteriormente
Francisco_Silva

Não vejo o porque o nome da variavel interferir na captura de evento do botão.

A cada for tu cria uma instancia do objeto e atribui a referencia a variavel “btnPrograma”:

btnPrograma = new JButton(i.getNome());

Ou seja, o nome do botão não é “btnPrograma”, btnPrograma é o nome da variavel que apartir deste momento contem a referencia a um objeto do tipo button que esta em algum lugar na memoria.
tudo o que tu fizer dentro deste laço do for apartir dai ira ser em relação a esse objeto que esta sendo referenciado por essa variavel.

Quando novamente tu passa nessa linha, reatribui uma nova referencia…
E novamente tudo o que tu fizer em seguida neste novo laço do for, sera em relação a esse novo ojeto.

Acredito que o problema esteja na implementação do listener, o ActionPerformed.

Tu pode também implementar o ActionListener para cada botton:

de vez isso

btnPrograma.addActionListener(this);

fazendo isso

btnPrograma.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //Implemente aqui a ação do botão. } });

Outra coisa…

panel.add(btnPrograma, gbc_labelnome);

“gbc_labelname” é o que exatamente?

E panel é um JPanel?

Yelden

Exato, e gbc era o gridpanel (de labels que agora sao buttons) que se transformou em um wraplayout…

Obrigado pela explicacao, para mim, btnPrograma era o objeto em si, e nao apenas uma referencia para o objeto, pelo que entendi, a cada iteracao do for, o objeto anterior se “perdia” (mas nao desaparecia pois ele aparecia no panel, apenas ficava inacessivel) e um novo se criava.

Eu geralmente crio um actionperformed para tratar todos os componentes, vou tentar mudar minha logica para fazer um actionperformed para cada iteracao do for…

@pmlm
Dessa maneira eu me referenciaria ao botao pelo nome (i.getNome), teria que pensar como eu relacionaria ele com os getSources, mas acho que esse eh o caminho, java reflection eh muito complicado.

Vou fazer os testes aqui… obrigado pelas dicas!

Francisco_Silva

Isso mesmo…
Os objetos não se perdem, mesmo que a variavel btnPrograma estaja referenciando a outro objeto o anterior que antes ela referenciava agora esta contido no container do Panel… ou seja, enquanto tiver alguém que no caso é o Panel, mantendo alguma referencia ao objeto ele continua a existir e manter todas as configurações que tu havia passado para ele, inclusive o actionListener.

Boa sorte ai.

Yelden

Obrigado pela ajuda,

Resolvi criando um Array de botões e colocando todos meus botões criados no laço dentro dele, assim eu posso referencialos usando as posições do array,
depois coloquei um laço for dentro do meu MouseListener, e percorri todos os botões (posições do array) executando o que eu queria.

ficou algo assim

nt cont=0;
			for (Programa i : programas){
								
				btnPrograma = new JButton(i.getNome());
				buttons[cont] = btnPrograma;
				btnPrograma.setIcon(new ImageIcon(Inicial2.class.getResource("/Icones/1393395397_document.png")));
				btnPrograma.setVerticalTextPosition(SwingConstants.BOTTOM); 
				btnPrograma.setHorizontalTextPosition(SwingConstants.CENTER);
				btnPrograma.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
				btnPrograma.setBorderPainted(false);
				btnPrograma.setContentAreaFilled(false);
				btnPrograma.setBounds(60, 382, 62, 50);
				//MyClickListener myclick = new MyClickListener();
				//btnPrograma.addMouseListener(myclick);
				btnPrograma.addMouseListener(this);
				
				GridBagConstraints gbc_labelnome = new GridBagConstraints();
				gbc_labelnome.insets = new Insets(0, 0, 0, 5);
				
				btnPrograma.setVisible(true);
				btnPrograma.setBorder(null);
				
				panel.add(btnPrograma, gbc_labelnome);
					
				cont++;
						
			}//Fim for

        @Override
	public void mouseClicked(MouseEvent e) {
		System.out.println("Click!");
		
		int cont=0;
		for (JButton i : buttons){
			
			if (e.getSource() == i){
				System.out.println("Botão "+cont);
				botaoSel = cont;
			}
			
			cont++;
		}
		
		
	}

Obrigado pelas idéias, problema resolvido :D

Criado 25 de fevereiro de 2014
Ultima resposta 26 de fev. de 2014
Respostas 5
Participantes 3