GARANTIR DESCONTO

Fórum Como eu faco 2 botões com 2 ActionListener/actionPerformed? #567609

09/04/2009

0

Como eu faco 2 botões com 2 ActionListener/actionPerformed em uma classe? Eu ainda estou aprendendo a mexer com o Swing. E não estou conseguindo. Codigo que estou usando:
package backdrive;
import javax.swing.*;
import java.awt.event.*;

public class Backdrive implements ActionListener {
	// Componentes
	private JLabel label;
	private JTextField textField;
	private JButton button;
	private JButton button2;

	// Painel (aonde fica os componentes)
	private JPanel panel;
	
	// Frame/Janela (aonde fica os paineis)
	private JFrame frame;

	private void Show() {
		// Inicia componentes.
		label = new JLabel("Seu nome:");
		textField = new JTextField(20);
		button = new JButton("Exibir");
		button2 = new JButton("Botao 2");

		// Eventos.
		button.addActionListener(this);
		button2.addActionListener(this);

		// Adiciona componentes ao painel.
		panel = new JPanel();
		panel.add(label);
		panel.add(textField);
		panel.add(button);
		panel.add(button2);

		// Adiciona painel a janela.
		frame = new JFrame("Janela");
		frame.add(panel);

		// Prepara para exibicao.
		frame.pack();
		
		// Colocamos como visivel.
		frame.setVisible(true);
		
		// Caso o usuario clique X, sai.
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	// Botão1 ?!?!
	public void actionPerformed(ActionEvent e) {
		String texto = textField.getText();
		JOptionPane.showMessageDialog(frame, texto);
	}

	// Botão2 ?!?1
	public void actionPerformed(ActionEvent e) {
		JOptionPane.showMessageDialog(frame, "Teste");
	}

	public static void main(String[] args) {
		new Backdrive().Show();
	}
}
Eu so consigo usar mais de 1 Action com duas classes...
Erros do Ecplise :


Duplicate method actionPerformed(ActionEvent) in type Backdrive	Backdrive/backdrive	Backdrive.java	line 50	

Duplicate method actionPerformed(ActionEvent) in type Backdrive	Backdrive/backdrive	Backdrive.java	line 56	

The type Backdrive must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent)	Backdrive/backdrive	Backdrive.java	

Eduardounder

Eduardounder

Responder

Posts

09/04/2009

Ricardo Silva

Olá Eduardo: Pelo que entendi você deseja tratar todos os eventos dos seus botões dentro da mesma classe onde você "montou" sua tela ok?? Pois bem... antes de mais nada é preciso lhe explicar que a utilização de tratamento de eventos "junto" com a "montagem" da tela vai lhe trazer muita dor de cabeça para fazer manutenções posteriores em seu código. Uma boa solução seria implementar o já conceituado padrão MVC na construção de seu aplicativo. Mas, respondendo à sua dúvida(e deixando de lado todos os bons mandamentos na construção de aplicativos OO), é possível ter uma única classe que implemente a interface ActionListener trantando os eventos de dois ou mais botões. Porém lembre-se: esta não é uma prática muito recomendada, à menos que dois ou mais botões possuam a mesma funcionalidade. Eis o código:
package br.com.learning;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class HelloButton extends JFrame implements ActionListener {

	private JButton botao1;
	private JButton botao2;
	
	public HelloButton(){
		initComponents();
		configEvents();
		configLayout();
	}
	
	private void configLayout(){
		this.setLayout(new FlowLayout());
		this.add(botao1);
		this.add(botao2);
		this.setSize(100,200);
		this.setVisible(true);
	}
	
	private void initComponents(){
		botao1 = new JButton("Botão 001");
		botao2 = new JButton("Botão 002");
	}
	
	private void configEvents(){
		botao1.addActionListener(this);
		botao2.addActionListener(this);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	
	/**
	 * Realiza o tratamento dos eventos dos botões.
	 */
	public void actionPerformed(ActionEvent e) {
			//trata os eventos para o botao "botao1"
			if( e.getSource() == botao1){
				JOptionPane.showMessageDialog(null, "Clicou sobre o botão 01");
			}
//			trata os eventos para o botao "botao2"
			if (e.getSource() == botao2){
				JOptionPane.showMessageDialog(null, "Clicou sobre o botão 02");
			}
	}

	public static void main(String[] args) {
		HelloButton hf = new HelloButton();
	}
	
}
Neste exemplo, você utiliza o método getSource() do objeto ActionEvent para analisar se a instância do objeto que está sendo recebido é a mesma do objeto que você deseja tratar. Perceba que esta abordagem tem dois problemas: 1 - Você utiliza o padrão de deenvolvimento estrutural para decicir o tratamento dos botões. 2 - Sempre que você necessitar adicionar mais botões à sua tela, você terá que inserir mais estruturas de controle
if(...){}
. Outra questão sobre o uso do método getSource(), é que você não conseguirá utilizá-lo se escrever uma classe de tratamento de eventos separada, porque aí você teria que toranr seus atributos públicos para acessá-los de dentro da classe "tratadora" o que feriria o princípio da OO de encapsulamento. Mas você pode me dizer: "dá pra passar meu botão como parâmetro para a classe tratadora", e eu respondo : "realmente dá, mas não fica legal e soa como GAMBI(arra)" Uma segunda abordagem seria fazer o uso de inner classes, ou classes implícitas:
package br.com.learning;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

public class HelloButton2 extends JFrame {
	private JButton botao1;
	private JButton botao2;
	
	public HelloButton2(){
		initComponents();
		configEvents();
		configLayout();
	}
	
	private void configLayout(){
		this.setLayout(new FlowLayout());
		this.add(botao1);
		this.add(botao2);
		this.setSize(100,200);
		this.setVisible(true);
	}
	
	private void initComponents(){
		botao1 = new JButton("Botão 001");
		botao2 = new JButton("Botão 002");
	}
	
	private void configEvents(){
		botao1.addActionListener(new RegraBotao1());
		botao2.addActionListener(new RegraBotao2());
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public static void main(String[] args) {
		HelloButton2 hf = new HelloButton2();
	}
	

class RegraBotao1 implements ActionListener{

	public void actionPerformed(ActionEvent e) {
		JOptionPane.showMessageDialog(null, "Clicou sobre o botão 01");
		
	}
		
}

class RegraBotao2 implements ActionListener{

	public void actionPerformed(ActionEvent e) {
		JOptionPane.showMessageDialog(null, "Clicou sobre o botão 02");
		
	}
		
}


}

Note que nesta segunda abordagem você também tem o problema de ter que ficar definindo N classes implícitas para cada N botões que você tiver. Se você utilizar o editor gráfico do netBeans(Matisse) ou utilizar o editor gráfico do eclipe(VE), vaiperceber que eles criam classe implícitas, porém de um jeito mais enxuto, diretamente na chamada do meto addActionListener do seu objeto. Particularmente eu não gosto disso, porque além de deixa o código uma verdadeira zo@$%, a sua regra de tratamento fica misturada com a regra de composição da sua tela. Então você me pergunta "Qual a melhor solução" e eu te respondo "Depende"... depende do tamanho e do objetivo do seu aplicativo, mas eu prefiro implementar o padrão [i]Chain of Responsibility[/i] de GOF para resolver esse tipo de problema. Espero ter lhe ajudado. Abraços Pra você se aprofundar mais, dá uma lida nestas referências: [url]http://java.sun.com/docs/books/tutorial/[/url] [url]http://java.sun.com/docs/books/tutorial/uiswing/components/button.html[/url] se você precisa implementar a mesma funcionalidade para dois ou mais componmentes:[url]http://java.sun.com/docs/books/tutorial/uiswing/misc/action.html[/url] Design patterns[url]http://www.argonavis.com.br/cursos/java/j930/index.html[/url] GOF:[url]http://compare.buscape.com.br/prod_unico?idu=1857307610&kw=8573076100&auto=2[/url]
Responder

Gostei + 0

09/04/2009

Eduardounder

Opa, obrigado pela resposta. Então agora estou tentando utilizar o editor visual do Eclipse, mas não estou conseguindo. Eu faco um JFrame (ele ja faz automaticamente um JContentPanel). Eu mando compilar e simplesmente não mostra nada! Tem algum comando que devo por no codigo para fazer com que aparece a janela? Aqui tá o codigo gerado pelo Eclipse.
package main;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JList;
import javax.swing.JButton;

public class Program {

	private JFrame jFrame = null;  //  @jve:decl-index=0:visual-constraint="59,28"
	private JPanel jContentPane = null;
	private JButton jButton = null;
	/**
	 * This method initializes jFrame
	 *
	 * @return javax.swing.JFrame
	 */
	private JFrame getJFrame() {
		if (jFrame == null) {
			jFrame = new JFrame();
			jFrame.setSize(new Dimension(373, 184));
			jFrame.setContentPane(getJContentPane());
		}
		return jFrame;
	}

	/**
	 * This method initializes jContentPane
	 *
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.add(getJButton(), BorderLayout.CENTER);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jButton
	 *
	 * @return javax.swing.JButton
	 */
	private JButton getJButton() {
		if (jButton == null) {
			jButton = new JButton();
			jButton.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()"); // TODO Auto-generated Event stub actionPerformed()
				}
			});
		}
		return jButton;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
	}

}
Obrigado, Eduardo.
Responder

Gostei + 0

09/04/2009

Ricardo Silva

Olá novamente Eduardo. Está faltando nesta sua classe você criar um construtor, definir o layout do seu JFrame incluindo o tamanho, posicionar os objetos visuais no seu painel de conteúdo e depois executar o método setVisible(true) do seu JFrame para que a tela seja exibida no monitor. Acontece que a ferramenta VE sempre irá criar "classes visuais" baseadas no padrão JavaBean [url]http://java.sun.com/products/javabeans/[/url]. Por isso você tem sempre um método [b]getSeuObjeto()[/b] que retornam os tipos apropriados dos objetos visuais que você quer trabalhar. Pra ser sincero e honesto, se você quiser aprender java mesmo, do jeito certo, então você deve esquecer que as IDES existem. Estas ferramentas são muito úteis pra quando você já estiver "maduro" suficiente na linguagem, e precise "ganhar tempo" criando suas aplicações. Para entender bem como funciona a criação de janelas, Frames, caixas de texto, botões etc... eu sugiro que você começe pelo tutorial da própria sun [url]http://java.sun.com/docs/books/tutorial/uiswing/index.html[/url]. Se você tiver problemas com o inglês leia os tutoriais do GUJ[url]www.guj.com.br[/url]. Procure aprender como escrever suas próprias "classes visuais" em um editor de textos simples. Entenda bem o processo de compilação, o conceito de "descobrimento" das classes no classpath da aplicação, e só então passe a utilizar uma IDE avançada como o Eclipse ou o NetBeans. No começo vai ser bem chato e talvez você até perca um pouco a motivação, mas se você não desistir, em pouco tempo estará entendendo bem como as coias se encaixam. Espero ter lhe ajudado de alguma forma. []'s
Responder

Gostei + 0

22/01/2014

António Freitas

Cá está o meu contributo, embora mt amador! :pray: :evil: package Applets; import java.applet.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExemploJButton { JFrame janela = new JFrame(); JButton botão1 = new JButton(); JButton botão2 = new JButton(); public static void main (String args[]) { new ExemploJButton(); } public ExemploJButton() { janela.setTitle("Exemplo de JButton"); janela.setSize(300, 70); janela.setLocation(100, 100); janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); janela.setLayout(new GridLayout (1,2)); botão1.setText("Fechar"); botão2.setText("OK"); janela.add(botão1); janela.add(botão2); botão1.addActionListener(null); botão2.addActionListener(null); janela.setVisible(true); } public void actionPerformed(ActionEvent e) { System.exit(0); { if (e.getSource()==botão2) { JOptionPane.showMessageDialog("Janela de botões"); } } } }
Responder

Gostei + 0

28/01/2014

André Pereira

[quote="gatolatindo"]Cá está o meu contributo, embora mt amador! :pray: :evil: package Applets; import java.applet.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExemploJButton { JFrame janela = new JFrame(); JButton botão1 = new JButton(); JButton botão2 = new JButton(); public static void main (String args[]) { new ExemploJButton(); } public ExemploJButton() { janela.setTitle("Exemplo de JButton"); janela.setSize(300, 70); janela.setLocation(100, 100); janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); janela.setLayout(new GridLayout (1,2)); botão1.setText("Fechar"); botão2.setText("OK"); janela.add(botão1); janela.add(botão2); botão1.addActionListener(null); botão2.addActionListener(null); janela.setVisible(true); } public void actionPerformed(ActionEvent e) { System.exit(0); { if (e.getSource()==botão2) { JOptionPane.showMessageDialog("Janela de botões"); } } } }
A melhor solução é criar 2 classes internas que implemente ActionListener, e para cada botão add uma instância da classe que ira tratar o evento do botão.
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar