JTextField - Dokumentarten: Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Die Seite wurde neu angelegt: „=IntegerDocument= Als erstes das IntegerDocument (es lässt euch nur Zahlen eingeben!) <code=java> //zuerst wie es gesetzt wird JTextField tmp = new JTextField()…“
 
Keine Bearbeitungszusammenfassung
Zeile 26: Zeile 26:
         }
         }
       super.insertString(offset,s, attributeSet);
       super.insertString(offset,s, attributeSet);
    }
}
</code=java>
Dies ist ganz simple und ich glaube für jeden zu verstehen
=DoubleDocument=
Nun hier noch ein DoubleDocument (damit auch Kommazahlen funktionieren!)
<code=java>
//Aufruf
JTextField text = new JTextField(new DoubleDocument(text));
text.setText("12.10");
//andere Klasse
  public class DoubleDocument extends PlainDocument
  {
    private boolean bDot = false;
    private JTextField jtTxt = null;
    public DoubleDocument(JTextField txt)
    {
      this.jtTxt = txt;
    }
    public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException
    {
      bDot = jtTxt.getText().toString().indexOf(".") == -1 ? false : true;
      try{
        if(s.indexOf(".") != -1 && s.length() > 1) //überprüfe einen ganzen String und nicht 1 Zeichen
          bDot = true;
        System.out.println(">>>> 3 >> " + bDot);
        if(!s.equals(".")) //wenn es sich um keinen KommaPunkt handelt
          Double.parseDouble(s);
        else if(bDot)
          throw new Exception();
        else
          bDot = true;
      }
      catch(Exception ex)  //only allow integer values
      {
        Toolkit.getDefaultToolkit().beep(); //macht einen Ton
        //System.out.println("Keine Zahl!");
        return ;
      }
      super.insertString(offset,s, attributeSet);
    }
  }
</code=java>
=DateDocument=
Nun ein DateDocument, was schon bißchen schwieriger zu verstehen ist, weil man gewisse Abfragen hat...
<code=java>
//zuerst, wie setze ich es
JTextField tmp = new JTextField();
tmp.setDocument(new DateDocument(tmp));
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.awt.event.KeyEvent;
import java.text.*;
import java.util.Date;
import java.util.GregorianCalendar;
public class DateDocument extends PlainDocument
{
  public String initString = "yyyy MM dd";
  private int ivorher = 0;
  Date datum = new Date();
  private String str;
  private static int sep1 = 4, sep2 = 7;
  private JTextComponent textComponent;
  private int newOffset;
  /**
  * Überprüft eingegebenes Zeichen auf seine Gültigkeit->
  * Buchstaben oder sonstige Zeichen sind nicht zulässig
  * @param tc JTextComponent
  */
  public DateDocument(JTextComponent tc)
  {
    textComponent = tc;
    try{
        insertString(0,initString,null);
      }
      catch(Exception ex) {
          ex.printStackTrace();
      }
  }
  /**
  * Versucht das eingegebene Zeichen auf einen Integer zu parsen. Zusätzlich wird
  * überprüft, wo sich der Cursor befindet (womöglich vor einem Trennzeichen, das
  * übersprungen werden soll). Tage und Monate werden bereits während der Eingabe
  * auf ihre Gültigkeit (z.B. Tag: 32 -> falsch, Monat: 13 -> falsch) überprüft.
  * @param offset  Position im String (ist zu vergleichem mit dem Initialisierungsstring)
  * @param s      Zeichen, das überprüft wird
  * @param attributeSet  AttributeSet wird nur an die Vaterklasse weitergeleitet
  * @throws BadLocationException  wird geworfen, wenn das Zeichen nicht geparst werden kann
  */
  public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException
  {
    if(s.equals(initString))
        super.insertString(offset,s,attributeSet);
    else
    {
        try
        {
            //DateFormat format = DateFormat.getDateInstance();
            SimpleDateFormat format = new SimpleDateFormat(initString);
            format.setLenient(false);      //ßberprüfung auf korrektes Datum
            Date dDatum = format.parse(s);
            super.remove(0,textComponent.getText().length());
            super.insertString(offset,s,attributeSet);
        }
        catch(Exception ex)
        {
            try
            {
              Integer.parseInt(s);
              newOffset = offset;
              if(atSeparator(offset))
              {
                newOffset++;
                textComponent.setCaretPosition(newOffset);
              }
              if(!dateIsOk(//textComponent.getText(0,newOffset)+
              s,newOffset))
              {
                  Toolkit.getDefaultToolkit().beep();
                  return;
              }
              super.remove(newOffset,1);
              super.insertString(newOffset,s,attributeSet);
            }
            catch(Exception ex2)
            {
              return; //only allow integer values
            }
        }
    }
  }
  /**
  *
  * @param offset  Position im String (ist zu vergleichen mit dem Inititialisierungsstring)
  * @param length  Länge des Strings
  * @throws BadLocationException  Wenn eine Position nicht verwendet bzw. ermittelt werden kann
  */
  public void remove(int offset, int length) throws BadLocationException
  {
    if(atSeparator(offset))
      textComponent.setCaretPosition(offset-1);
    else textComponent.setCaretPosition(offset);
  }
  /**
  * @param offset Position im String (ist zu vergleichen mit dem Initialisierungsstring)
  * @return boolean, true für Separater ist am offset, false für kein Separator
  */
  public boolean atSeparator(int offset)
  {
    return offset == sep1 || offset == sep2; //false
  }
  /**
  * Überprüft das eingegebene Datum auf seine Richtigkeit
  * @param txtDate  Zeichen (als String), das überprüft wird
  * @param off      Offset des Zeichens
  * @return        true für Datum ist ok, false für nicht möglich
  */
private boolean dateIsOk(String txtDate,int off)
{
  boolean ret = false;
  int curScan = 0;
  String cur = "";
  int len = 0;
  len = off+1;
  String svorher ="";
  String s ="";
  if(len < 1)
    curScan = 0;
  else curScan = len -1;
  try{
      s = initString.substring(len-1, len);
      if(curScan != 0)
        svorher = initString.substring(curScan-1, len-1);
      else
        svorher = "F";
      int izahl = Integer.parseInt(txtDate);
      if (s.compareTo("M")== 0)
      {
        if (svorher.compareTo("M") != 0)
        {
          if (izahl > 1)
            ret = false;
          else
            ret = true;
          ivorher = izahl;
        }
        else {
            if (ivorher == 1 && izahl > 2)
              ret = false;
            else if(ivorher == 0 && izahl == 0)
              ret = false;
            else
              ret = true;
            }
      }
      if (s.compareTo("d")==0 || s.compareTo("D")==0)
      {
        if (svorher.compareTo("d") !=0 && svorher.compareTo("D") !=0 )
        {
          if (izahl > 3)
            ret = false;
          else
            ret = true;
        ivorher = izahl;
        }
        else {
          if (ivorher == 3 && izahl > 1)
            ret = false;
          else if(ivorher == 0 && izahl == 0)
            ret = false;
          else
            ret = true;
        }
      }
      if(s.compareTo("y") == 0 || s.compareTo("Y")==0)
      {
        ret = true;
      }
    }catch(Exception ex){
      //ex.printStackTrace(System.out);  //soll nicht geworfen werden, weil Jahre noch nicht überprüft werden
                                //bringt Error, wenn an letzter Stelle noch Ziffer eingegeben wird.
    }
    finally{
      return ret;
    }
  }
}
</code=java>
Am besten ist, ihr spielt erst mal mit dem Integerdocument rum, wenn ihr das Datedocument noch nicht versteht.
=NegativeDoubleDocument=
Das DefaultKommazeichen ist ein <code>.</code> und er wandelt die <code>,</code> in einen Punkt um (auch während der Eingabe).
Zuweisen geht wie beim "normalen" DoubleDocument -> <code>DoubleDocument(JTextField)</code> also.
<code=java>
JTextField myField = new JTextField();
myField.setDocument(new NegativeDoubleDocument());
myField.setText("110000,100");
myField.setText("-200,20"); //das geht auch, alle "," werden durch "." ersetzt
</code=java>
Nun noch der Code von NegativeDoubleDocument.
<code=java>
import javax.swing.text.PlainDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.JTextField;
import java.awt.Toolkit;
public class NegativeDoubleDocument extends PlainDocument
{
  private boolean bDot = false;
      /***************************************************************************
      * Funktion erlaubt ein minus oder + (nicht sichtbar) in den Zahlen
      * @param offset int
      * @param s string
      * @param attributeSet att
      * @throws BadLocationException
      **************************************************************************/
      public void insertString(int offset, String s, AttributeSet attributeSet) throws
          BadLocationException
      {
        try
            {
              if(s.equals(",")) //ersetzt den , durch einen Punkt
                s = ".";
              bDot = getText(0,getLength()).indexOf(".") == -1 ? false : true; //merkt sich ob ein Punkt oder nicht
              if (s.length() > 1)
              {
                //wenn der String größer als 1 ist, ist es eine ganze IP und somit eine Schleife
                for(int x = 0; x != s.length(); x++)
                  insertString(x,s.substring(x,x+1).replaceFirst(",","."),null); //ersetzt , durch Punkt
                //mach gar nix, weil die for schleife alles macht!
                  return;
              }
              else if(s.equals("-"))
              {
                String strTmp = getText(0,getLength()); //holt sich den Text
                System.out.println(strTmp);
                if(strTmp.indexOf("-")!=-1) //schaut nach ob ein minus vorhanden ist
                  strTmp = strTmp.replaceAll("-",""); //wenn ja weg
                else
                  strTmp = "-" + strTmp;
                replace(0,getLength(),null,attributeSet);
                super.insertString(0,strTmp,attributeSet);
                return;
              }
              else if(s.equals("+")) //bei einem + einfach ein weiteres - hinzufügen
              {
                if(getText(0,getLength()).indexOf("-")!=-1)
                  insertString(0,"-",attributeSet); //ruft sich selbst mit - auf und dann kommt obige ßberprüfung
                return;
              }
              //OPTIONAL!! STATT DEM ± kann man jedes Zeichen nehmen oder komplett weglassen
              //wenn man irgendwelche Zeichen zB noch haben will <!--- OPTIONAL ---!>
              else if(s.equals("±"))
              {
                String strTmp = getText(0,offset);
                if(strTmp.indexOf("±") != -1)
                  strTmp = strTmp.replaceAll("±","");
                else
                  strTmp = "±" + strTmp;
                replace(0,getLength(),null,attributeSet);
                super.insertString(0,strTmp,attributeSet);
                return; //damit aufgehört wird
              }
              //ENDE OPTIONAL!!
            //wenn das aktuelle Zeichen kein punkt ist oder wenn es ein Punkt ist und schon ein Punkt eingegegeben ist
              else if(!s.equals(".") || bDot)  // ==  if(!(s.equals(".") && !bDot))
                Double.parseDouble(s);
            }
            catch(Exception ex)
            {
              Toolkit.getDefaultToolkit().beep();
              return;
            }
            super.insertString(offset,s, attributeSet);
          }
    }
}
</code=java>
=DocumentFilter=
Zitat: "Ich will ein JTextField so verändern, dass man maximal 8 Zeichen eingeben kann und nur Groß- und kleinbuchstaben zugelassen sind (also keine Sonderzeichen, Punkte, usw.)."
Wir könnten einen DocumentFilter setzen, etwa so:
<code=java>
int MAX = 8;
JTextField textfield = new JTextField(MAX);
((AbstractDocument) textfield.getDocument()).setDocumentFilter(new DocumentSizeFilter(MAX, "[A-Za-z]+"));
</code=java>
<code=java>
import javax.swing.text.*;
import java.awt.*;
import javax.swing.*;
public class DocumentSizeFilter extends DocumentFilter {
    private final int maxCharacters;
    private final String pattern;
    public DocumentSizeFilter(final int maxChars, final String pattern) {
        maxCharacters = maxChars;
        this.pattern = pattern;
    }
    @Override
    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
            throws BadLocationException {
        if (str.matches(pattern) && (fb.getDocument().getLength() + str.length() - length) <= maxCharacters) {
            super.replace(fb, offs, length, str, a);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
     }
     }
}
}
Zeile 32: Zeile 416:
[[Kategorie:Java]]
[[Kategorie:Java]]
[[Kategorie:Swing]]
[[Kategorie:Swing]]
--[[Benutzer:thE_29|thE_29]] (26.08.2004)

Version vom 13. August 2014, 19:32 Uhr

IntegerDocument

Als erstes das IntegerDocument (es lässt euch nur Zahlen eingeben!)

<code=java> //zuerst wie es gesetzt wird JTextField tmp = new JTextField(); tmp.setDocument(new IntegerDocument());

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*;

public class IntegerDocument extends PlainDocument {

  public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException
   {
     try{
            Integer.parseInt(s);
        }
        catch(Exception ex)   //only allow integer values
        {
           Toolkit.getDefaultToolkit().beep(); //macht ein DßT
           //System.out.println("Keine Zahl!");
           return ;
        }
     super.insertString(offset,s, attributeSet);
   }

} </code=java> Dies ist ganz simple und ich glaube für jeden zu verstehen


DoubleDocument

Nun hier noch ein DoubleDocument (damit auch Kommazahlen funktionieren!)

<code=java> //Aufruf JTextField text = new JTextField(new DoubleDocument(text)); text.setText("12.10");


//andere Klasse

  public class DoubleDocument extends PlainDocument
 {
   private boolean bDot = false;
   private JTextField jtTxt = null;
   public DoubleDocument(JTextField txt)
   {
     this.jtTxt = txt;
   }
   public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException
   {
     bDot = jtTxt.getText().toString().indexOf(".") == -1 ? false : true;
     try{
       if(s.indexOf(".") != -1 && s.length() > 1) //überprüfe einen ganzen String und nicht 1 Zeichen
         bDot = true;
       System.out.println(">>>> 3 >> " + bDot);
       if(!s.equals(".")) //wenn es sich um keinen KommaPunkt handelt
         Double.parseDouble(s);
       else if(bDot)
         throw new Exception();
       else
         bDot = true;
     }
     catch(Exception ex)   //only allow integer values
     {
       Toolkit.getDefaultToolkit().beep(); //macht einen Ton
       //System.out.println("Keine Zahl!");
       return ;
     }
     super.insertString(offset,s, attributeSet);
   }
 }

</code=java>


DateDocument

Nun ein DateDocument, was schon bißchen schwieriger zu verstehen ist, weil man gewisse Abfragen hat...

<code=java> //zuerst, wie setze ich es JTextField tmp = new JTextField(); tmp.setDocument(new DateDocument(tmp));

import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; import java.awt.event.KeyEvent; import java.text.*; import java.util.Date; import java.util.GregorianCalendar;

public class DateDocument extends PlainDocument {

 public String initString = "yyyy MM dd";
 private int ivorher = 0;
 Date datum = new Date();
 private String str;
 private static int sep1 = 4, sep2 = 7;
 private JTextComponent textComponent;
 private int newOffset;
 /**
  * Überprüft eingegebenes Zeichen auf seine Gültigkeit->
  * Buchstaben oder sonstige Zeichen sind nicht zulässig
  * @param tc JTextComponent
  */
 public DateDocument(JTextComponent tc)
 {
   textComponent = tc;
   try{
        insertString(0,initString,null);
      }
      catch(Exception ex) {
         ex.printStackTrace();
      }
 }


 /**
  * Versucht das eingegebene Zeichen auf einen Integer zu parsen. Zusätzlich wird
  * überprüft, wo sich der Cursor befindet (womöglich vor einem Trennzeichen, das
  * übersprungen werden soll). Tage und Monate werden bereits während der Eingabe
  * auf ihre Gültigkeit (z.B. Tag: 32 -> falsch, Monat: 13 -> falsch) überprüft.
  * @param offset  Position im String (ist zu vergleichem mit dem Initialisierungsstring)
  * @param s       Zeichen, das überprüft wird
  * @param attributeSet  AttributeSet wird nur an die Vaterklasse weitergeleitet
  * @throws BadLocationException  wird geworfen, wenn das Zeichen nicht geparst werden kann
  */
 public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException
 {
    if(s.equals(initString))
       super.insertString(offset,s,attributeSet);
    else
    {
        try
        {
           //DateFormat format = DateFormat.getDateInstance();
           SimpleDateFormat format = new SimpleDateFormat(initString);
           format.setLenient(false);       //ßberprüfung auf korrektes Datum
           Date dDatum = format.parse(s);
           super.remove(0,textComponent.getText().length());
           super.insertString(offset,s,attributeSet);
        }
        catch(Exception ex)
        {
            try
            {
              Integer.parseInt(s);
              newOffset = offset;
              if(atSeparator(offset))
              {
                newOffset++;
                textComponent.setCaretPosition(newOffset);
              }
              if(!dateIsOk(//textComponent.getText(0,newOffset)+
              s,newOffset))
              {
                 Toolkit.getDefaultToolkit().beep();
                 return;
              }
              super.remove(newOffset,1);
              super.insertString(newOffset,s,attributeSet);
            }
            catch(Exception ex2)
            {
              return; //only allow integer values
            }
        }
    }
 }
 /**
  *
  * @param offset  Position im String (ist zu vergleichen mit dem Inititialisierungsstring)
  * @param length  Länge des Strings
  * @throws BadLocationException  Wenn eine Position nicht verwendet bzw. ermittelt werden kann
  */
 public void remove(int offset, int length) throws BadLocationException
 {
    if(atSeparator(offset))
      textComponent.setCaretPosition(offset-1);
    else textComponent.setCaretPosition(offset);
 }
 /**
  * @param offset Position im String (ist zu vergleichen mit dem Initialisierungsstring)
  * @return boolean, true für Separater ist am offset, false für kein Separator
  */
 public boolean atSeparator(int offset)
 {
    return offset == sep1 || offset == sep2; //false
 }
 /**
  * Überprüft das eingegebene Datum auf seine Richtigkeit
  * @param txtDate  Zeichen (als String), das überprüft wird
  * @param off      Offset des Zeichens
  * @return         true für Datum ist ok, false für nicht möglich
  */
private boolean dateIsOk(String txtDate,int off)
{
  boolean ret = false;
  int curScan = 0;
  String cur = "";
  int len = 0;
  len = off+1;
  String svorher ="";
  String s ="";
  if(len < 1)
    curScan = 0;
  else curScan = len -1;

  try{
      s = initString.substring(len-1, len);
     if(curScan != 0)
        svorher = initString.substring(curScan-1, len-1);
     else
        svorher = "F";
     int izahl = Integer.parseInt(txtDate);

     if (s.compareTo("M")== 0)
     {
       if (svorher.compareTo("M") != 0)
       {
         if (izahl > 1)
           ret = false;
         else
           ret = true;
         ivorher = izahl;
       }
       else {
           if (ivorher == 1 && izahl > 2)
             ret = false;
           else if(ivorher == 0 && izahl == 0)
             ret = false;
           else
             ret = true;
           }
     }
     if (s.compareTo("d")==0 || s.compareTo("D")==0)
     {
       if (svorher.compareTo("d") !=0 && svorher.compareTo("D") !=0 )
       {
         if (izahl > 3)
           ret = false;
         else
           ret = true;
       ivorher = izahl;
       }
       else {
         if (ivorher == 3 && izahl > 1)
           ret = false;
         else if(ivorher == 0 && izahl == 0)
           ret = false;
         else
           ret = true;
       }
     }
     if(s.compareTo("y") == 0 || s.compareTo("Y")==0)
     {
       ret = true;
     }

   }catch(Exception ex){
     //ex.printStackTrace(System.out);   //soll nicht geworfen werden, weil Jahre noch nicht überprüft werden
                               //bringt Error, wenn an letzter Stelle noch Ziffer eingegeben wird.
   }
   finally{
     return ret;
   }
 }

} </code=java> Am besten ist, ihr spielt erst mal mit dem Integerdocument rum, wenn ihr das Datedocument noch nicht versteht.


NegativeDoubleDocument

Das DefaultKommazeichen ist ein . und er wandelt die , in einen Punkt um (auch während der Eingabe). Zuweisen geht wie beim "normalen" DoubleDocument -> DoubleDocument(JTextField) also.

<code=java> JTextField myField = new JTextField(); myField.setDocument(new NegativeDoubleDocument()); myField.setText("110000,100"); myField.setText("-200,20"); //das geht auch, alle "," werden durch "." ersetzt </code=java>

Nun noch der Code von NegativeDoubleDocument. <code=java> import javax.swing.text.PlainDocument; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.JTextField; import java.awt.Toolkit;

public class NegativeDoubleDocument extends PlainDocument {

 private boolean bDot = false;
      /***************************************************************************
      * Funktion erlaubt ein minus oder + (nicht sichtbar) in den Zahlen
      * @param offset int
      * @param s string
      * @param attributeSet att
      * @throws BadLocationException
      **************************************************************************/
     public void insertString(int offset, String s, AttributeSet attributeSet) throws
         BadLocationException
     {
       try
           {
             if(s.equals(",")) //ersetzt den , durch einen Punkt
               s = ".";
             bDot = getText(0,getLength()).indexOf(".") == -1 ? false : true; //merkt sich ob ein Punkt oder nicht
             if (s.length() > 1)
             {
               //wenn der String größer als 1 ist, ist es eine ganze IP und somit eine Schleife
               for(int x = 0; x != s.length(); x++)
                 insertString(x,s.substring(x,x+1).replaceFirst(",","."),null); //ersetzt , durch Punkt
               //mach gar nix, weil die for schleife alles macht!
                 return;
             }
             else if(s.equals("-"))
             {
               String strTmp = getText(0,getLength()); //holt sich den Text
               System.out.println(strTmp);
               if(strTmp.indexOf("-")!=-1) //schaut nach ob ein minus vorhanden ist
                 strTmp = strTmp.replaceAll("-",""); //wenn ja weg
               else
                 strTmp = "-" + strTmp;
               replace(0,getLength(),null,attributeSet);
               super.insertString(0,strTmp,attributeSet);
               return;
             }
             else if(s.equals("+")) //bei einem + einfach ein weiteres - hinzufügen
             {
               if(getText(0,getLength()).indexOf("-")!=-1)
                 insertString(0,"-",attributeSet); //ruft sich selbst mit - auf und dann kommt obige ßberprüfung
               return;
             }
             //OPTIONAL!! STATT DEM ± kann man jedes Zeichen nehmen oder komplett weglassen
             //wenn man irgendwelche Zeichen zB noch haben will