Galera tentei sozinho e tentei e tentei mas eu não consigo capturar quando a tecla ‘Ç’ é apertada¬¬ Eu uso InputMap e ActionMap, não trato os eventos com KeyListeners.
Com as outras letras do alfabeto e números não tenho problema( pelo menos não ainda ). Tenho apenas com o CEDILHA.
Meu método processaTeclas() está assim:
private void processaTeclas() {
botoesA = visaoPrincipal.getBotoesA();
/** * Captura o InputMap sempre que a janela atual está em foco e captura o ActionMap */
InputMap iMap = visaoPrincipal.getPainelPrincipal().getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW );
ActionMap aMap = visaoPrincipal.getPainelPrincipal().getActionMap();
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões numéricos*/
for( int i = 0; i < 10; i++ ) {
String actionName = "botaoN" + i;
aMap.put( actionName, acaoBotoesNumericos[i] = new BotaoNumericoAcao(i) );
iMap.put( KeyStroke.getKeyStroke("" + i), actionName );
iMap.put( KeyStroke.getKeyStroke("NUMPAD" + i), actionName );
}
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões de texto( alfabeto ) */
for( int i = 0; i < 27; i++ ) {
String actionName = "botaoA" + i;
String letra = botoesA[i].getText();
aMap.put( actionName, acaoBotoesAlfabeto[i] = new BotaoAlfabetoAcao(i) );
iMap.put( KeyStroke.getKeyStroke(letra), actionName );
}
}
E minha classe BotaoAlfabetoAcao está assim:
/**
* Classe interna responsável por capturar as teclas de texto( alfabeto ) e passar para a camada Model - Dados
*/
private class BotaoAlfabetoAcao extends AbstractAction {
int n;
public BotaoAlfabetoAcao( int n ) {
this.n = n;
}
@Override
public void actionPerformed( ActionEvent e ) {
dados.setAreaDeTexto(n);
}
}
Ai voce me pergunta, ué mas por que voce passa um número para o construtor de BotaoAlfabetoAcao e ele passa um numero para a areaDeTexto? Porque eu estou tentando fazer esse programa em MVC com swing, então botei as coisas separadas, Essa classe é a controller, e na dados, ele sabe o que notificar a visão de acordo com o que ele recebe. No caso como estou recebendo um INTEIRO, ele vai pegar esse inteiro na Model - Dados, que é o inteiro representando o número do elemento do botão no array. La na model, eu tenho um array com os botoes do alfabeto. E no caso se eu passar o valor 1() ele vai chamar o construtor sobrecarregado vai pegar o valor 1 e corresponder ao botao[1] = que é a letra B e vai exibir na tela, entendeu? Funciona com todos, menos com o CEDILHA.
EDIT: Só para constar, além do : “DEAD_CEDILLA”, já tentei “Ç” e ‘Ç’ e também não dá
Galera no caso você estão usando um método apenas, vou tentar postar aqui desde o começo para vê se vocês conseguem me ajudar que eu não estou conseguindo encontrar o meu erro de lógica de jeito nenhum.
Classe InterfaceGraficaPrincipal:
/** * O texto de cada botão é a letra correspondente. Ex: o texto do botaA é igual a "A", o texto do botaoCedilha é igual a "Ç", ou seja, quando eu der um ".getText()" no arrayDeBotao[numero].getText()" ele tem que retornar uma String com o "A" ou "B" ou "Ç", dependendo do Botão.
private void armazenaBotoesA() {
botoesA[0] = botaoA;
botoesA[1] = botaoB;
botoesA[2] = botaoC;
botoesA[3] = botaoD;
botoesA[4] = botaoE;
botoesA[5] = botaoF;
botoesA[6] = botaoG;
botoesA[7] = botaoH;
botoesA[8] = botaoI;
botoesA[9] = botaoJ;
botoesA[10] = botaoK;
botoesA[11] = botaoL;
botoesA[12] = botaoM;
botoesA[13] = botaoN;
botoesA[14] = botaoO;
botoesA[15] = botaoP;
botoesA[16] = botaoQ;
botoesA[17] = botaoR;
botoesA[18] = botaoS;
botoesA[19] = botaoT;
botoesA[20] = botaoU;
botoesA[21] = botaoV;
botoesA[22] = botaoW;
botoesA[23] = botaoX;
botoesA[24] = botaoY;
botoesA[25] = botaoZ;
botoesA[26] = botaoCedilha;
}
public JButton[] getBotoesA() {
return botoesA;
}
Classe ControleTecladoAlfanumerico
private void processaTeclas() {
botoesA = visaoPrincipal.getBotoesA();
/** * Captura o InputMap sempre que a janela atual está em foco e captura o ActionMap */
InputMap iMap = visaoPrincipal.getPainelPrincipal().getInputMap( JComponent.WHEN_IN_FOCUSED_WINDOW );
ActionMap aMap = visaoPrincipal.getPainelPrincipal().getActionMap();
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões numéricos*/
for( int i = 0; i < 10; i++ ) {
String actionName = "botaoN" + i;
aMap.put( actionName, acaoBotoesNumericos[i] = new BotaoNumericoAcao(i) );
iMap.put( KeyStroke.getKeyStroke("" + i), actionName );
iMap.put( KeyStroke.getKeyStroke("NUMPAD" + i), actionName );
}
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões de texto( alfabeto ) */
for( int i = 0; i < 27; i++ ) {
String actionName = "botaoA" + i;
String letra = botoesA[i].getText();
aMap.put( actionName, acaoBotoesAlfabeto[i] = new BotaoAlfabetoAcao(i) );
iMap.put( KeyStroke.getKeyStroke(letra), actionName );
}
}
E classe Interna BotaoAlfabetoAcao:
/**
* Classe interna responsável por capturar as teclas de texto( alfabeto ) e passar para a camada Model - Dados
*/
private class BotaoAlfabetoAcao extends AbstractAction {
int n;
public BotaoAlfabetoAcao( int n ) {
this.n = n;
}
@Override
public void actionPerformed( ActionEvent e ) {
dados.setAreaDeTexto(n);
}
}
E classe Dados:
/** * Cria um array de Botões para armazenar os botões com as letras do alfabeto */
private JButton[] botoesA = visaoPrincipal.getBotoesA();
/** * Configura/Notifica a área de texto da Visão para números */
public void setAreaDeTexto( String t ) {
visaoPrincipal.getAreaDeTexto().setText( visaoPrincipal.getAreaDeTexto().getText() + t );
}
/** * Configura/Notifica a área de texto da Visão para texto( alfabeto ) */
public void setAreaDeTexto( int e ) {
String letra = botoesA[e].getText();
visaoPrincipal.getAreaDeTexto().setText( visaoPrincipal.getAreaDeTexto().getText() + letra );
}
Que estranho! Estou quebrando a cabeça aqui pra te ajudar…
Coloca um Sysout aqui ó:
@Override
public void actionPerformed( ActionEvent e ) {
System.out.println("setArea: "+n);
dados.setAreaDeTexto(n);
}
Tchauzin![/quote]
Independente de não terem resolvido meu problema, pelo menos estão tentando me ajudar. Obrigado.
Pelo visto acho que isso que você falou, já ajuda um pouco. Eu fiz isso. E fui digitando letra por letra, não na ordem do teclado, mas sim na ordem alfabetica. E saída no console foi essa:
Ou seja, todas funcionaram, menos o Ç, eu apertei e nada aconteceu. E o meu Cedilha não está ruim, eu consigo digita-lo em outros programas e ja testei o programa em outro computador também e da no mesmo.
Tenho quase certeza que não é esse problema pois as outras letras também poderiam ser char mas eu usei String no lugar.
Se alguém quiser ver o código do programa inteiro para melhor visualização e me ajudar estarei postando aqui para download. Agradeço a ajuda de vocês e peço que ainda me ajudem, estou quebrando a cabeça para tentar encontrar esse maldito problema. Não quero deixa-lo de lado pois isso é experiência que se adquire.
Bom eu tentei usar o char e não apareceu nenhuma tecla dessa vez:
// NA CLASSE CONTROLE
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões de texto( alfabeto ) */
for( int i = 0; i < 26; i++ ) {
String actionName = "botaoA" + i;
char letra = botoesA[i].getText().charAt(0);
aMap.put( actionName, acaoBotoesAlfabeto[i] = new BotaoAlfabetoAcao(i) );
iMap.put( KeyStroke.getKeyStroke(letra), actionName );
}
// NA CLASSE DADOS
/** * Configura/Notifica a área de texto da Visão para texto( alfabeto ) */
public void setAreaDeTexto( int e ) {
char letra = botoesA[e].getText().charAt(0);
visaoPrincipal.getAreaDeTexto().setText( visaoPrincipal.getAreaDeTexto().getText() + letra );
}
Reparei algo que talvez seja interessante. Veja, coloquei Char ao inves de String como você disse. E coloquei um System.out.println no for e na classe interna. No for ele imprimiu tudo, mas na classe interna não. Será que os elementos não estão sendo passados para o construtor? Veja o código e a saída no console?
/** * Associa as ações aos objetos da classe Interna e associa as teclas aos Actions Maps para botões de texto( alfabeto ) */
for( int i = 0; i < 27; i++ ) {
String actionName = "botaoA" + i;
char letra = botoesA[i].getText().charAt(0);
aMap.put( actionName, acaoBotoesAlfabeto[i] = new BotaoAlfabetoAcao(i) );
iMap.put( KeyStroke.getKeyStroke(letra), actionName );
System.out.println(botoesA[i].getText() + " = " + letra);
}
private class BotaoAlfabetoAcao extends AbstractAction {
int numero;
public BotaoAlfabetoAcao( int n ) {
numero = n;
}
@Override
public void actionPerformed( ActionEvent e ) {
dados.setAreaDeTexto(numero);
System.out.printf( "\n\nElementos: %d", numero );
}
}
Saída no console:
A = A
B = B
C = C
D = D
E = E
F = F
G = G
H = H
I = I
J = J
K = K
L = L
M = M
N = N
O = O
P = P
Q = Q
R = R
S = S
T = T
U = U
V = V
W = W
X = X
Y = Y
Z = Z
Ç = Ç
Está vendo? Os números( elementos ) não foram impressos.
EDIT: Porém usando STRING os elementos são impressos quando eu aperto alguma tecla =/ Ta dificil de depurar essa bosta
[quote]
Há alguns pequenos erros nele e alguns ajustes:
Primeiro o for para criar os Action/InputMaps
Vc tem um array de 27 objetos (de zero a 26) mas para antes do último (que é justamente o cedilha).
Troquei por <=
for( int i = 0; i <= 26; i++ )
[b][/quote]
Isso na verdade não era erro. Eu tinha mudado quando eu tava tentando tratar o cedilha separadamente do loop entende?[/b]
Fiz as alterações, sendo que esse lance do UpperCase e Lower eu iria fazer depois que resolvesse esse maldito problema. Agora quanto ao charAt não tinha feito. Alias até fiz no outro post e te mostrei mas tava errado em algo.
Tem certeza que alterou a classe Dados? Esse método está o mesmo que o original, sem alteração nenhuma.
[size=18]De qualquer forma…OBRIGADOOOOOOOOOOOOOOOO>>>>> AGORA ESTÁ FUNCIONANDO :lol: :lol: :lol: [/size]
Qual era o erro? Tinha algo a ver com o InputMap? E quanto ao maisculo e minusculo, ele não está diferenciado. Quando eu digito, ele exibi sempre em maisculo seja com caps lock ligado ou não. Acredito que tem algo a ver com o metodo na classe Dados. Vou verificar aqui. E quanto ao projeto ser em "MVC", acho que estou conseguindo implementar bem esse padrão em Swing? Tentei fazer de acordo com a documentação que li no site da Oracle. MVC Modificado que tem lá também. Obrigado a todos que me ajudaram. Que disposeram de seu tempo me ajudando. Três dias parado olhando para esse código tentando achar o erro.
[quote=wellington.nogueira]com relação ao método setAreaDeTexto
Tinha um if e == 26 que colocava o Ç. Provavelmente você já tinha alterado o código
O problema é que o Ç não é algo padrão (como a Lina tinha comentado).
Quando vc usa String no getKeyStroke, ele já entende a letra maiúscula e minúscula porém ele espera caracteres mapeados (VK_algumacoisa), quando usa char, precisa mapear ambos os casos…
Não diria, neste caso que era erro, mas “particularidades” não bem documentadas
[/quote]
Hmm…Entendi. Caraca essa foi difícil. Só mas uma coisa, você percebeu, quando abriu o programa ai, que no visual editor o layout dele aparece de um jeito e, quando executa, fica de outro jeito? Eu usei layout em tudo, não sei por que ficou assim. Você tem alguma ideia?
[quote=wellington.nogueira][quote=lucas_guj]Hmm…Entendi. Caraca essa foi difícil. Só mas uma coisa, você percebeu, quando abriu o programa ai, que no visual editor o layout dele aparece de um jeito e, quando executa, fica de outro jeito? Eu usei layout em tudo, não sei por que ficou assim. Você tem alguma ideia?[/quote]Desculpe cara, mas não usei Visual Editor não (eu dificilmente uso um editor de telas). Mas o correto mesmo é utilizar layout managers sim.
Só uma observação: O Visual Editor foi “descontinuado” e agora há outro plugin: Window Builder. Há algumas versões do Visual Editor muito “bugadas” .[/quote]
Cara eu falei visual editor mas falei errado, na verdade quis dizer matisse do netBeans, mas não tem problema não, já consegui resolver, você faz as telas na mão ou usa arrasta e solta?
Não sei se faz muita diferença (e não deveria) mas eu usei o cedilha como char e não como String. Não cheguei a fazer o teste com o cedilha em forma de String.