Probleme mit JTextField und PlainDocument



  • Also, Ich will ein JTextField, das die Eingabe filtert. Es soll nur
    Zahlen und davon auch nur bestimmte annehmen. Das Ganze brauche ich für
    3 verschiedene Textfelder: Für ein Eingabefeld das nur Stunden annimmt,
    eines das nur Minuten und eines das das Datum annimmt.
    Das man das dadurch erreichen kann, indem man eine eigene Klasse von
    JTextField ableitet und darin die Methode createDefaultModel überschreibt
    und dann dieses DefaultModel in einer Klasse beschreibt, die von PlainDocument
    erbt, habe ich verstanden.
    Nicht versehen tue ich allerdings, das der Konstruktor von meinem abgeleiteten
    JTextField NACH dem abarbeiten der abgeleiteten Klasse von PlainDocument
    aufgerufen wird.
    Das ist deswegen wichtig, weil ich ja 3 unterschiedliche Eingamasken brauche.
    Um nicht insgesamt 6 Klassen schreiben zu müssen ( 3 abgeleitete JTextField und
    3 abgeleitete PlainDocument ) will ich also beim erstellen eines JTextField schon
    beim initiieren meine Wünsche mitteilen. Z.B so
    RestrictedField feld1 = new RestrictedField( 10, 5 );
    Dabei ist 10 die Gesamtlänge des Feldes und 5 die Anzahl der Zeichen, die das
    Textfeld maximal annimmt. GEHT ABER NICHT! Die 10 nimmt er brav an, die 5 hingegen
    nicht. Kopierts und schaut nach, welche Konstruktoren zuerst aufgerufen werden,
    es ist ZUERST der von PlainDocument!
    Dann habe ich versucht, das Ganze so zu lösen, indem ich in der Klasse
    createDefaultModel anstatt nur return eine Variable auf das neu erzeugte
    Plaindocument setzte und diese dann gebrauche, um in separaten Methoden meine Wünsche
    mitzuteilen. Ergebnis: NullPointerException!
    Was ist da los, wieso kriege ich es nicht gebacken, auf die von mir abgeleitete
    Klasse von PlainDocument zugreifen zu können!!??!!
    Das war Frage 1. Frage 2 ist etwas grundsätzlicher: Ich versteh nicht,
    wieso man manchmal auf Document und manchmal auf PlainDocument zugreift.
    In was wird denn nun reingeschrieben, in Document oder in PlainDocument?

    Vielen Dank fürs Schreiben im voraus, und hier der Quelltext:

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.text.*;
    import javax.swing.event.*;
    
    // Frame mit einem Textfeld
    public class NewPlainDoc extends JFrame
    {
      NewPlainDoc() {
    
         setSize( 300, 300 );
         setLocation( 200, 100 );
         Container content = getContentPane();
         // Erzeugt neues Eingabefeld
         RestrictedField eingabe = new RestrictedField(10,5);
         Panel mitte = new Panel();
    
         mitte.add( eingabe );
         content.add( mitte, BorderLayout.CENTER );
      }
    
      public static void main( String[] arg ) {
         NewPlainDoc f = new NewPlainDoc();
         f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
         f.show();
      }
    }
    
    // RestrictedField: Erbt von JTextField
    // und gibt ein spezielles PlainDocument zurück
    class RestrictedField extends JTextField
    {
       int max;
       RestrictedField( int length ) {
         this( length, 0 );
       }
       RestrictedField( int length, int max ) {
         super( length );
         this.max = max;
         System.out.println( "Wert max in Konstruktor RestrictedField : " + max );
       }
    
       protected Document createDefaultModel() {
         if( max == 0 )
          return new RestrictedDocument();
         else
          return new RestrictedDocument(max);
       }
    }
    
    // RestrictedDocument : Erbt von PlainDocument
    // und beschreibt eine Eingabemaske
    // die nur Zahlen und davon nur eine bestimmte
    // Anzahl zulässt
    class RestrictedDocument extends PlainDocument
    {
      int max;
    
      RestrictedDocument( int max ) {
        this.max = max;
        // Wird zuerst aufgerufen
        System.out.println( "Wert max in Konstruktor RestrictedDocument : " + max);
      }
      RestrictedDocument() {
        this(0);
      }
    
      public void insertString( int caret, String str, AttributeSet a )
       throws BadLocationException {
          if( max > 0 ) {
            if( getLength() > max )
             return;
            if( (getLength() + str.length()) > max )
              str = (str).substring( 0, max-getLength() );
          }
          char[] value = str.toCharArray();
          for( int i = 0; i < value.length; i++ ) {
            if( value[i] < '0' || value[i] > '9' )
              return;
          }
          super.insertString( caret, str, a );
      }
    }
    

Anmelden zum Antworten