2010-08-05 17 views
5

Tengo un campo de texto en mi aplicación. A pesar de ser un campo de texto, los usuarios a veces pegan grandes cantidades de texto en él. Además, otras funciones del problema establecen grandes cantidades también.¿Puedo limitar la longitud del texto en un JTextField que se puede pintar, mientras se almacena el texto completo?

A veces hay tanto texto que la JVM obtiene una infracción de acceso en fontmanager.dll. Oracle no parece estar interesado en solucionar el problema en sí, así que al menos quiero tratar de evitarlo.

Limitar la cantidad de texto que el usuario ingresa aparentemente no es aceptable (de lo contrario, esta sería la solución más obvia), pero es aceptable permitir que se establezca y luego deshabilitar el campo de texto. Cuando el texto está vinculado al modelo, debe contener el texto completo nuevamente.

Dado que esto es intrínsecamente un error en la vista, pensé que la solución debería estar en la vista, en lugar de trabajar en el modelo y agregar las propiedades adicionales allí.

Mi primer intento fue algo como esto:

public class LimitedTextField extends JTextField { 
    static final int LIMIT = 10000; 
    private String fullString; 

    @Override 
    public void setText(String text) { 
     if (text != null && text.length() > LIMIT) { 
      fullString = text; 
      setEnabled(false); 
     } else { 
      fullString = null; 
      super.setText(text); 
      setEnabled(true); 
     } 
    } 

    @Override 
    public String getText() { 
     if (fullString != null) { 
      return fullString; 
     } else { 
      return super.getText(); 
     } 
    } 
} 

Esto no pasan las pruebas de unidad ingenuas, pero una vez que escribí una prueba adicional para BeansBinding, he encontrado que no funciona porque no se une BeansBinding a la propiedad de texto, sino que se une al documento, simulando una propiedad de texto. Entonces getText() siempre devuelve una cadena vacía en esa prueba.

Ahora estoy tratando de hacer una implementación de documento que haga lo que quiero, pero seguro que no es fácil hacer este tipo de truco a nivel de documento. Puedo ver todos los métodos que tiene, pero no puedo encontrar una buena manera de limitar el texto sin también hacer que ese texto no esté disponible al llamar a getText().

Respuesta

1

Esta es una pregunta difícil sin duda. Desea afectar la pintura del campo con un impacto mínimo, además de no tratar de generar demasiado texto. La única sugerencia que tengo es considerar la creación de tu propia estrategia de pintura (ver http://forums.sun.com/thread.jspa?threadID=481290) y donde se dibuja el texto, simplemente dibuja un subconjunto de los caracteres. Podría tratar de crear un nuevo UIDelegate para dibujar el componente de texto, pero eso también podría ser bastante difícil. Este painting overview podría ayudarlo a orientarse en lo que respecta a la pintura personalizada. Este article podría ayudarlo a aplicar un delegado de IU personalizado en todos los campos de texto o solo en el que está intentando corregir.

1

En lugar de usar un JTextField quizás podría usar una línea sin formato JTextArea. Luego puede insertar un carácter de línea nueva en el Documento. Luego, cuando el texto esté pintado, solo verá una sola línea.

Probablemente necesite anular también el método getText() para eliminar el carácter de nueva línea. No estoy seguro de si ayuda, pero puede hacer que piense en una dirección diferente.

1

El documento de longitud limitada es realmente fácil de hacer. Por supuesto, hay varios enfoques, Aquí está el más simple (obras en producción en nuestro entorno):

package com.twist.ui.text.document; 

import javax.swing.text.AttributeSet; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.PlainDocument; 

public class LimitedLengthDocument extends PlainDocument { 
    private static final long serialVersionUID = 1L; 

    private int limit; 

    public LimitedLengthDocument(int limit) { 
     super(); 
     this.limit = limit; 
    } 

    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException { 
     if (str == null) 
      return; 

     // insert the string as usual. 
     super.insertString(offset, str, attr); 

     // If user tries to paste in a String that will not fit into the textfield, this approach will 
     // insert the text and remove the extra characters from the right.  

     // if resultant doc length is greater than the allowable size, truncate the document. 
     if(getLength() > limit ) 
      super.remove(limit, getLength() - limit); 
    } 
} 
Cuestiones relacionadas