Configurar listener de teclado

Olá gostaria de saber como se cria e configura listener para o teclado.

no exemplo de uma calculadora, utilizando o ActionListener e o metodo actionPerformed(), ele só funciona se o usuario clicar em cima dos JButtons, gostaria que executasse a mesma ação se o usuario apertasse alguma tecla do teclado, como poderia fazer isso?

um exemplo simples:


import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.GridLayout;

public class ExemploListener implements ActionListener {

	JFrame janela = new JFrame();
	JPanel painel = new JPanel(new GridLayout(2, 2, 10, 10));
	
	JButton numero1 = new JButton("1");
	JButton numero2 = new JButton("2");
	JButton numero3 = new JButton("3");
	JButton numero4 = new JButton("4");
	
	ExemploListener() {
		
		janela.setSize(200,200);
		janela.setTitle("Exemplo");
		janela.setLocation(200,150);
		janela.setResizable(false);
		janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		painel.add(numero1);
		painel.add(numero2);
		painel.add(numero3);
		painel.add(numero4);
		
		numero1.addActionListener(this);
		numero2.addActionListener(this);
		numero3.addActionListener(this);
		numero4.addActionListener(this);

		janela.add(painel);
		janela.setVisible(true);
	
	}
	
	public void actionPerformed(ActionEvent click) {
	
		if (click.getSource() == numero1) {
			JOptionPane.showMessageDialog(null, "1");
		}
		
		if (click.getSource() == numero2) {
			JOptionPane.showMessageDialog(null, "2");
		}
		
		if (click.getSource() == numero3) {
			JOptionPane.showMessageDialog(null, "3");
		}
		
		if (click.getSource() == numero4) {
			JOptionPane.showMessageDialog(null, "4");
		}
	
	}
	
	public static void main(String[] args) {
		new ExemploListener();
	}

}

Gostaria de criar listener para quando o usuario apertar a tecla “1” do teclado, exiba o JOptionPane com a mensagem, e assim para cada botao com seu numero, ou seja, executar a função por dois listener podendo ser pelo click (como já está) e também pelo teclado.

Grato

flw

:smiley:

vc precisa usar um keyListener e capturar o evento para cada botao, depois vc vai usar o metodo botao. setmnemonic(“TECLA_DESEJADA”) para dizer q aquela tecla é atalho para aquele botao.

Óla, estou enfrentando um problema para configurar um keylistener. Eu criei um Painel (uma classe que herda de JPanel) que possui um retangulo em gradiente que serve de background, e eu estou querendo ao apertar uma tecla do teclado, fazer um efeito de transição, porem nao estou conseguindo, pois alem de nao saber como fazer um efeito para fazer essa transição, to com problema com relaçao ao keylistener pois nao ta gerando o evento ao pressionar uma tecla

Segue o meu codigo:

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;

public class Principal2 extends JPanel
{
	private int pontox;
	private int pontoy;
	private int comp;
	private int alt;
	private Container cont;
	private JLabel lbl1;
	Graphics2D fundo;
	public Principal2()
	{
		setLayout(new BorderLayout());
		//setBackground (Color.BLACK);
		addKeyListener(new Teclado());
	}
	
	public void paintComponent (Graphics g)
	{
		super.paintComponent(g);
		fundo = (Graphics2D) g;
		fundo.setPaint(new GradientPaint (600, 0, Color.BLUE, 1, 0, Color.BLACK, true));
		this.pontox = ImageObserver.WIDTH;
		this.pontoy = ImageObserver.HEIGHT;
		this.comp = this.getWidth();
		this.alt = this.getHeight();
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		
		/*this.pontox = (this.getWidth() / 2) + 1;
		this.pontoy = ImageObserver.HEIGHT;
		//this.getHeight() / 2;
		this.comp = this.getWidth() / 2;
		this.alt = this.getHeight();
		//System.out.println ("Comprimento: " + this.getWidth());
		fundo.setPaint(new GradientPaint (600, 0, Color.BLACK, 1, 0, Color.BLUE, ));
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		*/
	}
	
	public static void main(String[] args) 
	{
		JFrame frm = new JFrame("Principal");
		frm.setBackground(Color.BLACK);
		frm.add(new Principal2());
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frm.setSize(800,600);
		frm.setVisible(true);
	}
	
	
	public class Teclado implements KeyListener
	{
		public Teclado (){};
		
		public void keyPressed (KeyEvent ke)
		{
			System.out.println("Codigo tecla " + ke.getKeyCode());
			System.out.println("Codigo vkdown " + KeyEvent.VK_A);
			if (ke.getKeyCode() == KeyEvent.VK_A)
			{
				lbl1 = new JLabel ("Teste");
				lbl1.setForeground(Color.yellow);
				lbl1.setFont(new Font ("Arial", Font.PLAIN, 30));
				add(lbl1);	
			}
		}
		
		public void keyReleased (KeyEvent ke)
		{}
		
		public void keyTyped (KeyEvent ke)
		{}
	}
}

Como eu posso resolver esse problema do teclado e tambem da transição da imagem, sendo que o que estou querendo fazer é um efeito semelhante ao do powerpoint, a imagem sumir degradando para o preto e depois reaparecer com um texto novo , e recriar o background com essa nova informaçao

Desde já agradeço

http://www.guj.com.br/java/47289-actionlistener-x-keylistener#258583

Eu tentei usando o procedimento do link, porem agora to com problema para fazer a açao que eu especifiquei, no caso inserir uma label nova a cada vez que eu pressiono a tecla up, ele so esta atualizando a janela se eu redimensiono ela, tanto para aumentar o tamanho quanto para voltar ao normal, a acao nao ocorre com a tela na posicao original, era para adicionar os componentes mesmo com a tela pequena, porem so aparece os componentes que foram adicionados se eu redimensionar a tela, e o inverso tambem acontece, queria saber o que esta acontecendo e como resolver isso.

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;

public class Principal2 extends JPanel
{
	private int pontox;
	private int pontoy;
	private int comp;
	private int alt;
	private Container cont;
	private JLabel lbl1;
	Graphics2D fundo;
	InputMap imap;
	ActionMap amap;

	public Principal2()
	{
		setLayout(new BorderLayout());
		setBackground (Color.BLACK);
		imap = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		imap.put(KeyStroke.getKeyStroke("UP"), this);
		//imap.put(KeyStroke.getKeyStroke("DOWN"), this);
		amap = this.getActionMap();
		amap.put(this , new AbstractAction (){
			public void actionPerformed (ActionEvent ae)
			{
				lbl1 = new JLabel ("Teste");
				add (lbl1);
				setBackground (Color.BLUE);
			}
		});
		/*amap.put(this, new AbstractAction()
						{
							public void actionPerformed (ActionEvent ae)
							{
								setBackground (Color.BLACK);
							}
						});
		*/
		//setBackground (Color.BLACK);
	}
	
	/*public void paintComponent (Graphics g)
	{
		super.paintComponent(g);
		fundo = (Graphics2D) g;
		fundo.setPaint(new GradientPaint (600, 0, Color.BLUE, 1, 0, Color.BLACK, true));
		this.pontox = ImageObserver.WIDTH;
		this.pontoy = ImageObserver.HEIGHT;
		this.comp = this.getWidth();
		this.alt = this.getHeight();
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		
		/*this.pontox = (this.getWidth() / 2) + 1;
		this.pontoy = ImageObserver.HEIGHT;
		//this.getHeight() / 2;
		this.comp = this.getWidth() / 2;
		this.alt = this.getHeight();
		//System.out.println ("Comprimento: " + this.getWidth());
		fundo.setPaint(new GradientPaint (600, 0, Color.BLACK, 1, 0, Color.BLUE, ));
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		
	}*/
	
	public static void main(String[] args) 
	{
		JFrame frm = new JFrame("Principal");
		//frm.setBackground(Color.BLACK);
		frm.add(new Principal2());
		frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frm.setSize(800,600);
		frm.setVisible(true);
	}
}

Eu comentei o metodo paintComponent pois queria testar esse recurso primeiro, queria saber se eu fiz alguma coisa errada, e tambem eu queria que a tela mudasse de cor a cada interaçao, ou seja, mudasse para azul quando pressionasse UP e para preto de novo quando pressionasse DOWN, como posso fazer isso.

Eu nao expliquei direito o meu problema, é que eu consegui fazer o procedimento do link, ele ta respondendo aos comandos do teclado, porem eu estou com problema em adicionar uma label quando eu aperto a tecla, pois o programa deve mudar a cor da tela e adicionar uma jlabel nesse painel, porem isso nao ta acontecendo, eu usei as duas constantes de JComponent, a JLabel so aparece se por exemplo, eu redimensionar a tela e apertar a tecla que eu configurei no InputMap e depois fazer ela voltar ao tamanho original, ou se eu apertar a tecla com a tela no tamanho normal e redimensionar a tela, fora isso nao aparece. A cor da tela muda, mas o componente que eu especifiquei nao é adicionado.O que pode estar acontecendo??

O componente(no caso o “painel”) só é desenhado no momento que você abre o programa. Para ele ser redesenhado, alguma alteração externa no componente deve ocorrer, tipo você minimizar a janela, redimensiona-la. Se você quer o componente seja redesenhado sem ter que redimensionar nada, você precisa usar pesquisar sobre os métodos repaint() e revalidate(). É o possível que só o repaint() já resolva, mas tem vezes que é preciso usar o revalidate() tambem.

Eu testei aqui e funcionou, mas agora quero tirar mais duas duvidas, uma é que eu quero associar duas teclas para fazer as açoes no painel, uma para mudar a cor da tela para azul e colocar a label, e a outra eu quero que mude para preto e altere a cor do texto na label, porem so esta funcionando a primeira tecla, a segunda nao ta funcionando, queria saber uma forma de associar duas teclas a duas acoes diferentes no componente, no caso o painel, e outra, queria saber como fazer um efeito de transicao na tela, semelhante ao powerpoint??

Segue o meu codigo:


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Janela extends JFrame
{
	private Principal2 panel;
	private InputMap imap;
	private ActionMap amap;
	private JLabel lbl1;
	private Action acao1 = new acaoPanel("mudar tela");
	private Action acao2 = new acaoPanel("mudar texto");
	private Container cont;
	
	public Janela ()
	{
		super("Teste");
		panel = new Principal2 ();
		this.setContentPane(panel);
		
		imap = 	panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		imap.put(KeyStroke.getKeyStroke("UP"), "panel");
		imap.put(KeyStroke.getKeyStroke("DOwN"), "panel.lbl1colorchanged");
		amap = panel.getActionMap();
		amap.put("panel", acao1);
		amap.put("panel.lbl1colorchanged", acao2);
		setSize (400, 400);
		setVisible (true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public class acaoPanel extends AbstractAction
	{
		
		String opcao;
		
		public acaoPanel (String acao)
		{
			this.opcao = acao;
		}
		
		public void actionPerformed (ActionEvent e)
		{	
			panel.setBackground(Color.BLUE);
			lbl1 = new JLabel ("Teste");
			add(lbl1);
			repaint();
			revalidate();
		}
	}
	
	public static void main(String[] args) 
	{
		Janela frame = new Janela();
	}

}

Esse é o codigo da classe Principal2, que é o painel

import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.*;
import javax.swing.*;

public class Principal2 extends JPanel
{
	private int pontox;
	private int pontoy;
	private int comp;
	private int alt;
	private Container cont;
	Graphics2D fundo;
	

	public Principal2()
	{
		setLayout(new FlowLayout());
		setBackground (Color.BLACK);
	}
	
	/*public void paintComponent (Graphics g)
	{
		super.paintComponent(g);
		fundo = (Graphics2D) g;
		fundo.setPaint(new GradientPaint (600, 0, Color.BLUE, 1, 0, Color.BLACK, true));
		this.pontox = ImageObserver.WIDTH;
		this.pontoy = ImageObserver.HEIGHT;
		this.comp = this.getWidth();
		this.alt = this.getHeight();
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		
		/*this.pontox = (this.getWidth() / 2) + 1;
		this.pontoy = ImageObserver.HEIGHT;
		//this.getHeight() / 2;
		this.comp = this.getWidth() / 2;
		this.alt = this.getHeight();
		//System.out.println ("Comprimento: " + this.getWidth());
		fundo.setPaint(new GradientPaint (600, 0, Color.BLACK, 1, 0, Color.BLUE, ));
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		
	}*/
}

Não precisa ir em outro tópico meu caro, é só aguardar a comunidade mesmo. Se não virem esse tópico, não vão ver o outro também.

Mas voltando ao seu problema. O caso é que no mesmo action performed você só executa uma ação, sem diferenciar uma da outra. Você fez certo ao criar a propriedade opcao na sua classe acaoPanel, mas voce não está usando ela em lugar nenhum, percebe? Você cria e diz que alteração você está fazendo no construtor. Mas na hora de executar a ação, você não verifica que opção é aquela.

Eu até poderia digitar o código pra funcionar, mas quero que você entenda o que você precisa fazer. Tente alterar seu tópico e , caso não consiga o que queria, poste aqui novamente.

E quando ao efeito de transição, não existe forma simples de fazer isso. Mas um caminho é seguir os tutorias do ponto V:
http://pontov.com.br/site/java/48-java2d/124-desenho-direto-active-rendering

Me desculpe, é que eu tinha feito isso no codigo, e construia a classe com um texto, tipo, “mudar texto” e “mudar tela”, dai se fosse pra mudar texto eu mudaria apenas o texto do jlabel, se fosse pra mudar a cor da tela, ele mudava a cor do JPanel, e eu criei dois objetos de açao com essas duas strings passadas para o construtor, e coloquei um metodo equals, para comparar qual string eu tava digitando, porem o problema esta no mapeamento de mais uma tecla para o jpanel, a primeira açao esta disparando certo, porem quando tento usar a segunda tecla, nao to conseguindo, como pode ver no codigo, eu mapeei duas teclas, up e down , para fazer açoes no painel e tambem no jlabel, porem nao ta dando certo, pois a primeira tecla no caso upfunciona, agora a segunda nao ta disparando uma açao, eu me esqueci de colocar o codigo certo do metodo actionPerformed, mas eu tentei fazer um condicional, porem a segunda tecla que eu configurei, down, nao funcionou, e quando fui alterar o codigo para usar o repaint e revalidate esqueci de colocar o condicional novamente. O que to querendo fazer é conseguir gerar mais uma ação ao apertar down e que essa açao ocorra no painel, por isso estou construindo a classe acao painel de outra forma, e no metodo actionPerformed eu verifico qual é a opcao que o usuario queira fazer, porem nao ta dando certo. Como posso mapear duas teclas para fazer acoes em um componente, se eu preciso criar duas classes extendendo AbstractAction, ou se posso usar apenas uma e verificar qual a tecla que lançou o evento??

Cara, desculpa, mas nesse último post você escreveu frases tão longas que eu não consegui entender o que você quis dizer. Faça frases menores, mostres trechos de código ao qual você deseja ajuda, separe tudo em paragrafos de no máximos 5 linhas.

Se você fez um código diferente do que está ai no seu post anterior, coloque ele ai tambem.

Ta certo entao, mas eu analisei o codigo aqui e consegui acertar o problema que tava tendo, meu note ta com problema com uma tecla aqui, mas eu mapeei outra tecla e consegui fazer funcionar. O que eu quero fazer agora é fazer a aplicação ficar em full screen e ter os efeitos do powerpoint, o fullscreen ate consegui, porem nao ta totalmente fullscreen, aparece umas partes cinza, nao sei por que.

Olhei o link que me passou e tambem pesquisei, e achei uma maneira de fazer o efeito usando o pacote com.sun.AWTUtilities, porem vi que esse pacote nao faz parte da API do Java e ate nao foi incluido em atualizaçoes recentes, dai queria saber uma maneira de simular o efeito, que eu acredito que seja um fade in/fade out, onde o constraste da tela é reduzido para preto e depois volta a imagem com algo diferente. Como posso fazer isso???

O codigo do programa ta assim agora:


public class Janela extends JFrame
{
	private Principal2 panel;
	private InputMap imap;
	private ActionMap amap;
	private JLabel lbl1;
	private Action acao1 = new acaoPanel("texto");
	private Action acao2 = new acaoPanel("tela");
	private Container cont;
	
	public Janela ()
	{
		super("Teste");
		panel = new Principal2 ();
		this.setContentPane(panel);
		//panel.setBackground(Color.BLUE);
		lbl1 = new JLabel ("Teste");			
		panel.add(lbl1);
		imap = 	panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
		imap.put(KeyStroke.getKeyStroke("LEFT"), "panel");
		imap.put(KeyStroke.getKeyStroke("RIGHT"), "panel.lbl1colorchanged");
		amap = panel.getActionMap();
		amap.put("panel", acao1);
		amap.put("panel.lbl1colorchanged", acao2);
		//setSize (400, 400);
		pack();
		setVisible (true);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public class acaoPanel extends AbstractAction
	{
		String opcao;
		public acaoPanel (String opcao)
		{
			this.opcao = opcao;
		}
		
		
		public void actionPerformed (ActionEvent e)
		{	
			if (this.opcao.equals("texto"))
			{
				lbl1.setText("Teste2");
			}
			else if (this.opcao.equals("tela"))
			{
				lbl1.setForeground(Color.WHITE);
				//panel.setBackground(Color.BLUE);
			}
			repaint();
			revalidate();
		}
	}
		
	public static void main(String[] args) 
	{
		GraphicsDevice tela = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
		Janela frame = new Janela();
		//frame.setUndecorated(true);
		//frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
		tela.setFullScreenWindow(frame);
	}

}

A classe principal2 é essa daqui:

public class Principal2 extends JPanel
{
	private int pontox;
	private int pontoy;
	private int comp;
	private int alt;
	private Container cont;
	Graphics2D fundo;
	

	public Principal2()
	{
		setLayout(new FlowLayout());
		setBackground (Color.BLACK);
	}
	
	public void paintComponent (Graphics g)
	{
		super.paintComponent(g);
		fundo = (Graphics2D) g;
		fundo.setPaint(new GradientPaint (600, 0, Color.BLUE, 1, 0, Color.BLACK, true));
		this.comp = this.getWidth();
		this.alt = this.getHeight();
		fundo.fillRect(0, 0, this.comp, this.alt);
		
		/*this.pontox = (this.getWidth() / 2) + 1;
		this.pontoy = ImageObserver.HEIGHT;
		//this.getHeight() / 2;
		this.comp = this.getWidth() / 2;
		this.alt = this.getHeight();
		//System.out.println ("Comprimento: " + this.getWidth());
		fundo.setPaint(new GradientPaint (600, 0, Color.BLACK, 1, 0, Color.BLUE, ));
		fundo.fillRect(this.pontox, this.pontoy, this.comp, this.alt);
		*/
	}
}

PAra fazer um programa em full screen, utilize o tutorial e veja se consegue adequar:
http://docs.oracle.com/javase/tutorial/extra/fullscreen/index.html

O resto num posso ajudar porque num num conheço