Tengo problemas con las máscaras en un JFormattedTextFieldproblemas con la supresión de las máscaras en un JFormattedTextField
entiendo que reemplaza los caracteres no válidos con un espacio, o lo que se define a través de setPlaceholderCharacter, pero lo que se necesita do permite la eliminación o el retroceso, y NO inserta un espacio en lugar del carácter que eliminé , siempre que el resto de la cadena esté permitida en la máscara.
Por ejemplo, con la máscara: *#*****
, la cadena "12 abc"
es válida.
Si coloca el cursor entre los caracteres byc y presiona el botón de retroceso, necesito que elimine el b, lo que da como resultado "12 ac"
. En cambio, lo elimina y agrega un espacio, convirtiéndose en: "12 a c"
.
A continuación se muestra un ejemplo de código simple para demostrar.
Agradeceré cualquier idea o ejemplo para evitar este problema.
public class testFrame extends javax.swing.JFrame {
public testFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.FlowLayout());
setMinimumSize(new Dimension(300,150));
java.awt.Button closeButton = new java.awt.Button();
JFormattedTextField maskTextField = new JFormattedTextField();
maskTextField.setMinimumSize(new Dimension(100,30));
getContentPane().add(maskTextField);
closeButton.setLabel("close");
closeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
});
getContentPane().add(closeButton);
try {
MaskFormatter someMask = new MaskFormatter("*#****");
DefaultFormatterFactory formatterFactory
= new DefaultFormatterFactory(someMask);
maskTextField.setFormatterFactory(formatterFactory);
} catch (ParseException ex) {
ex.printStackTrace();
}
maskTextField.setText("12 abc");
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new testFrame().setVisible(true);
}
});
}
}
código de actualización para reflejar respuesta a continuación. Agregué un segundo campo para que pueda ver el comportamiento con y sin la solución. También una solución menor, cambié el tamaño de las ventanas y lo centré en la pantalla para hacerlo más amigable.
testFrame clase pública se extiende javax.swing.JFrame {
public testFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(300, 200));
getContentPane().setLayout(new java.awt.FlowLayout());
JFormattedTextField maskTextField = new JFormattedTextField();
maskTextField.setMinimumSize(new Dimension(100,30));
getContentPane().add(maskTextField);
JFormattedTextField maskTextField2 = new JFormattedTextField();
maskTextField2.setMinimumSize(new Dimension(100,30));
getContentPane().add(maskTextField2);
java.awt.Button closeButton = new java.awt.Button();
closeButton.setLabel("close");
closeButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
});
getContentPane().add(closeButton);
try {
MaskFormatter someMask = new MaskFormatter("*#****");
DefaultFormatterFactory formatterFactory =
new DefaultFormatterFactory(someMask);
maskTextField.setFormatterFactory(formatterFactory);
MaskFormatter someMask2 = new MaskFormatter("*#****");
DefaultFormatterFactory formatterFactory2 =
new DefaultFormatterFactory(someMask2);
maskTextField2.setFormatterFactory(formatterFactory2);
} catch (ParseException ex) {
ex.printStackTrace();
}
maskTextField.setText("12 abc");
maskTextField2.setText("12 abc");
// added per suggestion below
if (maskTextField.getFormatter() instanceof DefaultFormatter) {
DefaultFormatter f = (DefaultFormatter) maskTextField.getFormatter();
f.setAllowsInvalid(true);
// options are:
// JFormattedTextField.COMMIT
// JFormattedTextField.COMMIT_OR_REVERT --> default
// JFormattedTextField.REVERT
// JFormattedTextField.PERSIST
maskTextField.setFocusLostBehavior(JFormattedTextField.PERSIST);
}
pack();
this.setLocationRelativeTo(null);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new testFrame().setVisible(true);
}
});
}
}
suena como un pequeño error: una máscara es algo con un lenght_ _fixed, cada posición de llenado, ya sea por un carácter válido o una placeHolder. Al eliminar un char, se reemplaza por placeHolder, en su ejemplo es el predeterminado, que es un espacio. Entonces el primer espacio es diferente del segundo, semánticamente :-) Cambie el lugar al otro, para ver la diferencia.Como su requisito parece ser algo así como cualquier-char-up-to-a-max-of-4-after-a-digit, tendrá que implementar un formateador personalizado ya que @DuncanJones ya sugirió – kleopatra
No me importa siendo de longitud fija, y supongo que solo tengo un caso de uso especial que no atendieron. Por ejemplo, si su máscara era (###) ### - ### e intentaba escribir (123) 456-7890 y había escrito accidentalmente dos 2, es decir, (122) 345-6789, la máscara estándar comportamiento parece significar que si elimina los primeros 2, sustituiría un espacio (marcador de posición) que le da (12) 345-6789. Necesito que elimine el carácter y agregue el marcador de posición al final de la cadena. Pero supongo que esto no es algo que otros necesitan, así que tendré que hacer un formateador personalizado :( –
ahh ... ya veo, gracias por la aclaración – kleopatra