Boa tarde a todos.
Preciso de ajuda com um problema que não estou conseguindo chegar a uma solução, talvez não estou usando a lógica correta, segue:
Tenho um combo box editável, e nele são carregadas descrições específicas de um plano de contas contábil, como por exemplo:
- Pago nota fiscal nr. * - *
- Pago passagem a * conforme recibo nr. *
- Pago aluguel a * ref. mês * c/r *
Porém, o usuário só poderá inserir/digitar informações nas posições onde estão os asteriscos, o restante do texto deve ser fixo, isto é, não pode ser apagada ou editada por outras informações (daí a ideia de usar o combo, pois o usuário apenas deverá entrar com as informações pré definidas).
Os asteriscos também não devem aparecer no combo, então antes de carregar as informações nele, eu faço um replaceAll e guardo a informação original (com os asteriscos) em uma variável quando o evento ItemStateChanged é disparado.
Atualmente estou adicionando eventos ao componente editor do combo, não sei se estou no caminho certo, porém ainda não funciona 100%:
String complemento = "";
String complementoAnterior = "";
jComboBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
//Aqui busco a descrição com os asteriscos no banco de dados e guardo na variável "complemento".
// Ex.: complemento = "Pago nota fiscal nr. * - *";
}
});
((JTextField)jComboBox.getEditor().getEditorComponent()).addKeyListener(new java.awt.event.KeyAdapter() {
// No evento keyPressed capturo a informação do combo e guardo na variável "complementoAnterior" antes do usuário digitar algo.
public void keyPressed(java.awt.event.KeyEvent evt) {
// Guardo o texto na variável.
complementoAnterior = ((JTextField)jComboBox.getEditor().getEditorComponent()).getText();
// Divido o complemento original em partes.
String partes [] = complemento.split("\\*");
for(String parte : partes){
parte = parte.replaceAll("\\s+$", ""); // Remove os espaços da direita.
parte = parte.replaceAll("^\\s+", ""); // Remove os espaços da esquerda.
// Verifico se o texto do combo não contém as partes do complemento original. Se não contiver, a variável recebe o valor do complemento original.
if(!((JTextField)jComboBox.getEditor().getEditorComponent()).getText().contains(parte)){
complementoAnterior = complemento.replaceAll("\\*", "");
}
}
}
// No evento keyReleased, caso não encontre as partes originais do complemento após o usuário inserir alguma informação, insiro no campo o texto capturado no evento anterior.
public void keyReleased(java.awt.event.KeyEvent evt) {
// Divido o complemento original em partes.
String partes [] = complemento.split("\\*");
for(String parte : partes){
parte = parte.replaceAll("\\s+$", ""); // Remove os espaços da direita.
parte = parte.replaceAll("^\\s+", ""); // Remove os espaços da esquerda.
// Verifico se o texto do combo não contém as partes do complemento original.
if(!((JTextField)jComboBox.getEditor().getEditorComponent()).getText().contains(parte)){
// Pego a posição do cursor no campo.
int posicao = ((JTextField)jComboBox.getEditor().getEditorComponent()).getCaretPosition();
// Insere o texto anterior no campo, já que o usuário digitou a informação na posição errada.
((JTextField)jComboBox.getEditor().getEditorComponent()).setText(complementoAnterior);
// Após alterar o texto, a posição do cursor vai para o fim, então preciso voltar para a posição anterior.
if(complementoAnterior.length() > posicao){
((JTextField)jComboBox.getEditor().getEditorComponent()).setCaretPosition(posicao);
}else{
((JTextField)jComboBox.getEditor().getEditorComponent()).setCaretPosition(complementoAnterior.length());
}
}
}
}
});
Da forma que está no código acima, os caracteres inseridos nas posições erradas são logo removidos, porém não gostaria que funcionasse dessa forma.
Outra tentativa que fiz, foi a seguinte:
String complemento = "";
jComboBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
//Aqui busco a descrição com os asteriscos no banco de dados e guardo na variável "complemento".
// Ex.: complemento = "Pago nota fiscal nr. * - *";
}
});
public void keyReleased(java.awt.event.KeyEvent evt) {
// Divido o complemento original em partes.
String partes [] = complemento.split("\\*");
// Guardo a posição do cursor no campo.
int posicao = ((JTextField)jComboBox.getEditor().getEditorComponent()).getCaretPosition();
// Essa variável receberá as partes do complemento, conforme elas forem sendo percorridas no loop.
String parte_aterior = "";
// Guardo o texto do combo na variável "texto".
String texto = ((JTextField)jComboBox.getEditor().getEditorComponent()).getText();
for(String parte : partes){
/* Se a posição do cursor for maior/igual que o tamanho da primeira parte ou maior/igual que o tamanho da parte anterior,
e se a posição for menor/igual que o início da parte do complemento no texto ou se a posição for maior/igual ao tamanho da parte,
o campo se torna editável, caso contrário o campo não é editável. */
if((posicao >= texto.indexOf(parte)+parte.length() || posicao >= texto.indexOf(parte_aterior)+parte_aterior.length()) && (posicao <= texto.indexOf(parte) || posicao >= texto.indexOf(parte)+parte.length())){
((JTextField)jComboBox.getEditor().getEditorComponent()).setEditable(true);
//evt.consume();
}else{
((JTextField)jComboBox.getEditor().getEditorComponent()).setEditable(false);
//evt.consume();
}
parte_aterior += parte;
}
Da forma que está no código acima, deveria funcionar exatamente como preciso, quando o cursor está na posição errada o campo não aceita caracteres porque não fica editável, quando está na posição correta ele fica editável, mas consigo apagar as partes do texto que deveriam ser fixas.
No sistema contábil atual do cliente, em Delphi, quando o cursor está na posição correta, o usuário consegue inserir/digitar informações, e quando não está, o texto não é editável, apenas é selecionável.
Portanto, gostaria de fazer funcionar da mesma forma em Java.
Essa é minha primeira postagem aqui no fórum, então me desculpem caso eu tenha me expressado mal.
Se alguém puder me ajudar, seja com dicas, exemplos e/ou sugestões, fico agradecido.
Obrigado.