validar try solo numeros longitud letras enteros decimales consola catch java swing jtextfield

try - validar solo letras en un jtextfield java



¿Hay alguna forma de aceptar solo valores numéricos en un JTextField? (19)

Además, considere usar un InputVerifier .

¿Hay alguna forma de aceptar solo valores numéricos en un JTextField ? ¿Hay algún método especial para esto?



Como esta pregunta reaparece bastante a menudo, puse un poco más de esfuerzo en esta respuesta que normalmente solía hacer.

Mi voto va al JFormattedTextField . OMI cada desarrollador de Swing debe tener una versión mejorada de esa clase en su conjunto de herramientas, ya que permite validar casi cualquier cosa que se le ocurra mediante la opción correcta de Format . Ejemplos para los cuales ya lo usé:

  • Entrada de cadena donde la String no puede estar vacía
  • Entrada coordinada
  • Entrada de fecha
  • Editor en un JSpinner
  • Escalas del mapa
  • Números
  • ...

También permite comentarios visuales cuando la entrada no es válida, que no es el caso con el InputVerifier . Todavía permite al usuario ingresar cualquier cosa, pero ese valor simplemente no se acepta cuando no es válido y ese valor nunca abandona la UI. Creo (pero, nuevamente, esa es mi opinión) que es mejor permitir que el usuario escriba una entrada no válida que simplemente eliminarla automáticamente, por ejemplo, con un DocumentFilter . Sospecho que hay un error al escribir un carácter en un campo de texto y no aparece.

Permítanme ilustrar esto con algún código (bastante código en realidad). Primero, la pequeña aplicación de demostración. Esta aplicación solo muestra un JFormattedTextField para números. El solo uso de otro formato permite reutilizar ese componente para validaciones completamente diferentes.

import be.pcl.swing.ImprovedFormattedTextField; import javax.swing.*; import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.NumberFormat; /** * See http://.com/q/1313390/1076463 */ public class FormattedTextFieldDemo { public static void main( String[] args ) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame testFrame = new JFrame( "FormattedTextFieldDemo" ); NumberFormat integerNumberInstance = NumberFormat.getIntegerInstance(); ImprovedFormattedTextField integerFormattedTextField = new ImprovedFormattedTextField( integerNumberInstance, 100 ); integerFormattedTextField.setColumns( 20 ); testFrame.add( createButtonPanel( integerFormattedTextField ), BorderLayout.NORTH ); final JTextArea textArea = new JTextArea(50, 50); PropertyChangeListener updateTextAreaListener = new PropertyChangeListener() { @Override public void propertyChange( PropertyChangeEvent evt ) { textArea.append( "New value: " + evt.getNewValue() + "/n" ); } }; integerFormattedTextField.addPropertyChangeListener( "value", updateTextAreaListener ); testFrame.add( new JScrollPane( textArea ), BorderLayout.CENTER ); testFrame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE ); testFrame.pack(); testFrame.setVisible( true ); } } ); } private static JPanel createButtonPanel( final JFormattedTextField aTextField ){ JPanel panel = new JPanel( new BorderLayout( ) ); panel.add( aTextField, BorderLayout.WEST ); Action action = new AbstractAction() { { aTextField.addPropertyChangeListener( "editValid", new PropertyChangeListener() { @Override public void propertyChange( PropertyChangeEvent evt ) { setEnabled( ( ( Boolean ) evt.getNewValue() ) ); } } ); putValue( Action.NAME, "Show current value" ); } @Override public void actionPerformed( ActionEvent e ) { JOptionPane.showMessageDialog( null, "The current value is [" + aTextField.getValue() + "] of class [" + aTextField.getValue().getClass() + "]" ); } }; panel.add( new JButton( action ), BorderLayout.EAST ); return panel; } }

que solo muestra un ImprovedFormattedTextField y un JButton que solo se habilita cuando la entrada es válida (aha, come esa solución de DocumentFilter ). También muestra un JTextArea en el que el valor se imprime cada vez que se encuentra un nuevo valor válido. Al presionar el botón, se muestra el valor.

El código para ImprovedFormattedTextField se puede encontrar a continuación, junto con ParseAllFormat del que depende

package be.pcl.swing; import javax.swing.JFormattedTextField; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.Color; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.text.Format; import java.text.ParseException; /** * <p>Extension of {@code JFormattedTextField} which solves some of the usability issues</p> */ public class ImprovedFormattedTextField extends JFormattedTextField { private static final Color ERROR_BACKGROUND_COLOR = new Color( 255, 215, 215 ); private static final Color ERROR_FOREGROUND_COLOR = null; private Color fBackground, fForeground; /** * Create a new {@code ImprovedFormattedTextField} instance which will use {@code aFormat} for the * validation of the user input. * * @param aFormat The format. May not be {@code null} */ public ImprovedFormattedTextField( Format aFormat ) { //use a ParseAllFormat as we do not want to accept user input which is partially valid super( new ParseAllFormat( aFormat ) ); setFocusLostBehavior( JFormattedTextField.COMMIT_OR_REVERT ); updateBackgroundOnEachUpdate(); //improve the caret behavior //see also http://tips4java.wordpress.com/2010/02/21/formatted-text-field-tips/ addFocusListener( new MousePositionCorrectorListener() ); } /** * Create a new {@code ImprovedFormattedTextField} instance which will use {@code aFormat} for the * validation of the user input. The field will be initialized with {@code aValue}. * * @param aFormat The format. May not be {@code null} * @param aValue The initial value */ public ImprovedFormattedTextField( Format aFormat, Object aValue ) { this( aFormat ); setValue( aValue ); } private void updateBackgroundOnEachUpdate() { getDocument().addDocumentListener( new DocumentListener() { @Override public void insertUpdate( DocumentEvent e ) { updateBackground(); } @Override public void removeUpdate( DocumentEvent e ) { updateBackground(); } @Override public void changedUpdate( DocumentEvent e ) { updateBackground(); } } ); } /** * Update the background color depending on the valid state of the current input. This provides * visual feedback to the user */ private void updateBackground() { boolean valid = validContent(); if ( ERROR_BACKGROUND_COLOR != null ) { setBackground( valid ? fBackground : ERROR_BACKGROUND_COLOR ); } if ( ERROR_FOREGROUND_COLOR != null ) { setForeground( valid ? fForeground : ERROR_FOREGROUND_COLOR ); } } @Override public void updateUI() { super.updateUI(); fBackground = getBackground(); fForeground = getForeground(); } private boolean validContent() { AbstractFormatter formatter = getFormatter(); if ( formatter != null ) { try { formatter.stringToValue( getText() ); return true; } catch ( ParseException e ) { return false; } } return true; } @Override public void setValue( Object value ) { boolean validValue = true; //before setting the value, parse it by using the format try { AbstractFormatter formatter = getFormatter(); if ( formatter != null ) { formatter.valueToString( value ); } } catch ( ParseException e ) { validValue = false; updateBackground(); } //only set the value when valid if ( validValue ) { int old_caret_position = getCaretPosition(); super.setValue( value ); setCaretPosition( Math.min( old_caret_position, getText().length() ) ); } } @Override protected boolean processKeyBinding( KeyStroke ks, KeyEvent e, int condition, boolean pressed ) { //do not let the formatted text field consume the enters. This allows to trigger an OK button by //pressing enter from within the formatted text field if ( validContent() ) { return super.processKeyBinding( ks, e, condition, pressed ) && ks != KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ); } else { return super.processKeyBinding( ks, e, condition, pressed ); } } private static class MousePositionCorrectorListener extends FocusAdapter { @Override public void focusGained( FocusEvent e ) { /* After a formatted text field gains focus, it replaces its text with its * current value, formatted appropriately of course. It does this after * any focus listeners are notified. We want to make sure that the caret * is placed in the correct position rather than the dumb default that is * before the 1st character ! */ final JTextField field = ( JTextField ) e.getSource(); final int dot = field.getCaret().getDot(); final int mark = field.getCaret().getMark(); if ( field.isEnabled() && field.isEditable() ) { SwingUtilities.invokeLater( new Runnable() { @Override public void run() { // Only set the caret if the textfield hasn''t got a selection on it if ( dot == mark ) { field.getCaret().setDot( dot ); } } } ); } } } }

La clase ParseAllFormat :

package be.pcl.swing; import java.text.AttributedCharacterIterator; import java.text.FieldPosition; import java.text.Format; import java.text.ParseException; import java.text.ParsePosition; /** * <p>Decorator for a {@link Format Format} which only accepts values which can be completely parsed * by the delegate format. If the value can only be partially parsed, the decorator will refuse to * parse the value.</p> */ public class ParseAllFormat extends Format { private final Format fDelegate; /** * Decorate <code>aDelegate</code> to make sure if parser everything or nothing * * @param aDelegate The delegate format */ public ParseAllFormat( Format aDelegate ) { fDelegate = aDelegate; } @Override public StringBuffer format( Object obj, StringBuffer toAppendTo, FieldPosition pos ) { return fDelegate.format( obj, toAppendTo, pos ); } @Override public AttributedCharacterIterator formatToCharacterIterator( Object obj ) { return fDelegate.formatToCharacterIterator( obj ); } @Override public Object parseObject( String source, ParsePosition pos ) { int initialIndex = pos.getIndex(); Object result = fDelegate.parseObject( source, pos ); if ( result != null && pos.getIndex() < source.length() ) { int errorIndex = pos.getIndex(); pos.setIndex( initialIndex ); pos.setErrorIndex( errorIndex ); return null; } return result; } @Override public Object parseObject( String source ) throws ParseException { //no need to delegate the call, super will call the parseObject( source, pos ) method return super.parseObject( source ); } }

Posibles mejoras:

  • el setBackground no es respetado por todos los Look-and-Feels. A veces puede usar setForeground en setForeground lugar, pero incluso eso no está garantizado para ser respetado por todos los L & F. Entonces, para comentarios visuales, sería mejor usar un signo de exclamación colocado al lado del campo. El inconveniente es que esto podría arruinar un diseño si de repente agrega / elimina un icono
  • la retroalimentación solo indica que la entrada es válida / inválida. No hay nada que indique cuál es el formato esperado. Una posible solución es usar una extensión de Format creada por el JFormattedTextField que incluya una descripción / ejemplo de entrada válida, y poner eso como información sobre herramientas en JFormattedTextField .

Concluyendo la cantidad de vistas que está recibiendo esta pregunta, no encontré ninguna de las soluciones anteriores adecuadas para mi problema. Decidí hacer un PlainDocument personalizado para satisfacer mis necesidades. Esta solución también emite un pitido cuando se alcanza el número máximo de caracteres utilizados, o el texto insertado no es un número entero.

private class FixedSizeNumberDocument extends PlainDocument { private JTextComponent owner; private int fixedSize; public FixedSizeNumberDocument(JTextComponent owner, int fixedSize) { this.owner = owner; this.fixedSize = fixedSize; } @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if (getLength() + str.length() > fixedSize) { str = str.substring(0, fixedSize - getLength()); this.owner.getToolkit().beep(); } try { Integer.parseInt(str); } catch (NumberFormatException e) { // inserted text is not a number this.owner.getToolkit().beep(); return; } super.insertString(offs, str, a); } }

implementado de la siguiente manera:

JTextField textfield = new JTextField(); textfield.setDocument(new FixedSizeNumberDocument(textfield,5));


Creo que es la mejor solución:

JTextField textField = new JFormattedTextField(new MaskFormatter("###")); //


Esta pregunta fue citada como un "duplicado exacto" de otra pregunta que se ha cerrado desde entonces. Las respuestas a esta pregunta fueron tan pobres que me inspiré para ayudar a cualquiera que pudiera encontrarlo más tarde, al vincular una respuesta mucho mejor para este caso de uso.

Es una respuesta a la pregunta cerrada y se puede resumir como ...

Use un JSpinner en JSpinner lugar.



Pruébelo en el evento de tecla presionada para el JTextField relacionado.

private void JTextField(java.awt.event.KeyEvent evt) { // TODO add your handling code here: char enter = evt.getKeyChar(); if(!(Character.isDigit(enter))){ evt.consume(); } }


Puede crear un hermoso campo de texto en Java que acepte o permita solo valores numéricos. Incluso puede establecer la precisión de los valores flotantes ... verifique el code en zybocodes


Te gustaría echar un vistazo a JFormattedTextField

Los campos de texto formateados proporcionan una forma para que los desarrolladores especifiquen el conjunto válido de caracteres que pueden escribirse en un campo de texto

Esta es una subclase de JTextField, por lo que puedes usarla así:

JTextField textField = new JFormattedTextField(NumberFormat.getInstance());


Un enfoque simple es subclasificar JTextField y anular createDefaultModel () devolviendo la subclase PlainDocument personalizada. Ejemplo: un campo de texto solo para enteros:

public class NumberField extends JTextField { @Override protected Document createDefaultModel() { return new Numberdocument(); } class Numberdocument extends PlainDocument { String numbers="1234567890-"; @Override public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { if(!numbers.contains(str)); else super.insertString(offs, str, a); } }

Ingrese la entrada en insertString () de cualquier manera.


Una solución muy fácil es usar un oyente de acción.

TextFieldActionPerformed(java.awt.event.ActionEvent evt) { try{ Integer.parseInteger(TextField.getText()); } catch(Exception e){ JOptionPane.showMessageDialog(null, "Please insert Valid Number Only"); TextField.setText(TextField.getText().substring(0,TextField.getText().length()-1)); } }

Puedes usarlo también para el doble:

Double.parseDouble(TextField.getText());


Una solución rápida:

JTextField textField = new JTextField() { public void processKeyEvent(KeyEvent ev) { char c = ev.getKeyChar(); if (c >= 48 && c <= 57) { // c = ''0'' ... c = ''9'' super.processKeyEvent(ev); } } };

El problema con la solución anterior es que el usuario no puede usar las teclas Eliminar, Flecha izquierda, Flecha derecha o Retroceso en el campo de texto, por lo que sugiero usar esta solución:

this.portTextField = new JTextField() { public void processKeyEvent(KeyEvent ev) { char c = ev.getKeyChar(); try { // Ignore all non-printable characters. Just check the printable ones. if (c > 31 && c < 127) { Integer.parseInt(c + ""); } super.processKeyEvent(ev); } catch (NumberFormatException nfe) { // Do nothing. Character inputted is not a number, so ignore it. } } };


Use el formatter para formatear el campo de texto.

NumberFormat format = NumberFormat.getInstance(); format.setGroupingUsed(false); NumberFormatter formatter = new NumberFormatter(format); formatter.setValueClass(Integer.class); formatter.setMaximum(65535); formatter.setAllowsInvalid(false); formatter.setCommitsOnValidEdit(true); myTextField = new JFormattedTextField(formatter);


escribe este código en la clave escrita

char c=evt.getKeyChar(); if(!(Character.isDigit(c) || (c==KeyEvent.VK_BACK_SPACE || c==KeyEvent.VK_DELETE))) { getToolkit().beep(); evt.consume(); }



DataTF.addKeyListener(new KeyAdapter() { @Override public void keyTyped(KeyEvent eve) { String AllowedData="0123456789."; char enter = eve.getKeyChar(); if (!AllowedData.contains(String.valueOf(enter))) { eve.consume(); } } });


if (JTextField.getText().equals("") || !(Pattern.matches("^[0-9]+$", JTextField.getText()))) { JOptionPane.showMessageDialog(null, " JTextField Invalide !!!!! "); }

  • if JTextField.getText (). equals ("") == -> si JTextField está vacío
  • if (! (Pattern.matches ("^ [0-9] + $", JTextField.getText ()))) == -> si TextField contiene otros caracteres distintos a los
  • JOptionPane.showMessageDialog (null, "JTextField Invalide !!!!!"); == -> entonces este mensaje aparecerá

import javax.swing.*; import javax.swing.text.*; public class JNumberTextField extends JTextField { private static final char DOT = ''.''; private static final char NEGATIVE = ''-''; private static final String BLANK = ""; private static final int DEF_PRECISION = 2; public static final int NUMERIC = 2; public static final int DECIMAL = 3; public static final String FM_NUMERIC = "0123456789"; public static final String FM_DECIMAL = FM_NUMERIC + DOT; private int maxLength = 0; private int format = NUMERIC; private String negativeChars = BLANK; private String allowedChars = null; private boolean allowNegative = false; private int precision = 0; protected PlainDocument numberFieldFilter; public JNumberTextField() { this( 10, NUMERIC ); } public JNumberTextField( int maxLen ) { this( maxLen, NUMERIC ); } public JNumberTextField( int maxLen, int format ) { setAllowNegative( true ); setMaxLength( maxLen ); setFormat( format ); numberFieldFilter = new JNumberFieldFilter(); super.setDocument( numberFieldFilter ); } public void setMaxLength( int maxLen ) { if (maxLen > 0) maxLength = maxLen; else maxLength = 0; } public int getMaxLength() { return maxLength; } public void setPrecision( int precision ) { if ( format == NUMERIC ) return; if ( precision >= 0 ) this.precision = precision; else this.precision = DEF_PRECISION; } public int getPrecision() { return precision; } public Number getNumber() { Number number = null; if ( format == NUMERIC ) number = new Integer(getText()); else number = new Double(getText()); return number; } public void setNumber( Number value ) { setText(String.valueOf(value)); } public int getInt() { return Integer.parseInt( getText() ); } public void setInt( int value ) { setText( String.valueOf( value ) ); } public float getFloat() { return ( new Float( getText() ) ).floatValue(); } public void setFloat(float value) { setText( String.valueOf( value ) ); } public double getDouble() { return ( new Double( getText() ) ).doubleValue(); } public void setDouble(double value) { setText( String.valueOf(value) ); } public int getFormat() { return format; } public void setFormat(int format) { switch ( format ) { case NUMERIC: default: this.format = NUMERIC; this.precision = 0; this.allowedChars = FM_NUMERIC; break; case DECIMAL: this.format = DECIMAL; this.precision = DEF_PRECISION; this.allowedChars = FM_DECIMAL; break; } } public void setAllowNegative( boolean value ) { allowNegative = value; if ( value ) negativeChars = "" + NEGATIVE; else negativeChars = BLANK; } public boolean isAllowNegative() { return allowNegative; } public void setDocument( Document document ) { } class JNumberFieldFilter extends PlainDocument { public JNumberFieldFilter() { super(); } public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { String text = getText(0,offset) + str + getText(offset,(getLength() - offset)); if ( str == null || text == null ) return; for ( int i=0; i<str.length(); i++ ) { if ( ( allowedChars + negativeChars ).indexOf( str.charAt(i) ) == -1) return; } int precisionLength = 0, dotLength = 0, minusLength = 0; int textLength = text.length(); try { if ( format == NUMERIC ) { if ( ! ( ( text.equals( negativeChars ) ) && ( text.length() == 1) ) ) new Long(text); } else if ( format == DECIMAL ) { if ( ! ( ( text.equals( negativeChars ) ) && ( text.length() == 1) ) ) new Double(text); int dotIndex = text.indexOf(DOT); if( dotIndex != -1 ) { dotLength = 1; precisionLength = textLength - dotIndex - dotLength; if( precisionLength > precision ) return; } } } catch(Exception ex) { return; } if ( text.startsWith( "" + NEGATIVE ) ) { if ( !allowNegative ) return; else minusLength = 1; } if ( maxLength < ( textLength - dotLength - precisionLength - minusLength ) ) return; super.insertString( offset, str, attr ); } } }