# Controls eines Formulars durchlaufen



## Toast78 (1. Jan 2007)

Guden Tach!

Um zu überprüfen, ob alle Pflichtfelder gefüllt wurden, möchte ich gerne alle Controls eines JFrame-Formulars durchlaufen und ihren Namen überprüfen (Name wurde bereits eingetragen) 

```
/**
   * Überprüft die Pflichtfelder.
   * @param pflichtfelder Namen der Controls, die überprüft werden sollen.
   * @return false, wenn nicht in jedem Control Werte eingetragen wurden.
   */
  public boolean pruefePflichtfelder(String[] pflichtfelder, 
                                      Component control) {
    java.awt.Component[] controls = this.getComponents();
    boolean ergebnis = true;

    for (int i = 0; i < pflichtfelder.length && ergebnis; i++) {
      for (int j = 0; j < controls.length && ergebnis; j++) {
        if (controls[j].getName() != null) {
          if (controls[j].getName().equals(pflichtfelder[i])) {
            if (controls[j] instanceof javax.swing.JTextField) {
              if (((javax.swing.JTextField) controls[j]).getText().equals("")) {
                ergebnis = false;
                control = controls[j];
              }
            }
          }
        }
      }
    }
    
    return ergebnis;
  }
```
Naja, so hatte ich mir das jedenfalls vorgestellt. Dummerweise entält das Array controls nur ein Element. Erste Frage ist jetzt: 
Wo finde ich den Container, in dem alle Controls abgespeichert sind?

Zweite Frage: Ich habe fast alle Controls zur Gruppierung in JPanels gepackt. Ergibt sich dadurch für mich ein Nachteil (falls es eine Lösung zur ersten Frage gibt)?

Danke schonmal fürs Lesen


----------



## nocxsville (1. Jan 2007)

Mir persönlich wäre das Vorgehen zu aufwändig und vor allem zu anfällig. In welcher Klasse befindet sich denn die Methode? Im Panel oder in einer externen Klasse? Falls ja in welcher?

Gruß,
nocxsville.


----------



## Toast78 (1. Jan 2007)

Mir wären 9-12 If-Anweisungen zu aufwändig. Und warum soll das zu anfällig sein? Klar, Felder, deren Überprüfung abhängig ist von anderen Feldern, kann man schlecht überprüfen. Aber ansonsten wüsste ich nicht, was daran anfällig sein sollte.

Die Methode befindet sich in der Formklasse und wird abgearbeitet beim Klicken auf einen JButton cmdSpeichern.


----------



## Guest (1. Jan 2007)

```
private void collectEmptyFields( Container container, List<JTextField> list )
{
  for( int i=0, n=container.getComponentCount(); i<n; i++ )
  {
     Component component = container.getComponent(i);
     // Nur aktive Komponenten holen
     if( component.isEnabled())
     {
        if( component instanceof JTextField )
        {
           JTextField textField = (JTextField)component;
           // Nur editierbare, leere Textfelder holen
           if( textField.isEditable() && 0 == textField.getText().trim().length() )
           {
              list.add(textField);
           }
        }
        else if( component instanceof Container )
        {
           // Container rekursiv durchgehen
           collectEmptyFields((Container)component, list);
        }
        // Alle anderen Komponenten ignorieren
     }
  }
}
```


----------



## Guest (1. Jan 2007)

Übrigens, schau dir auch javax.swing.InputVerifier an.


----------



## Toast78 (1. Jan 2007)

Ich bedanke mich erstmal für die Hilfe vom "Gast" 
Die Prozedur war doch der Wink in die richtige Richtung. Komisch, dass Java bzw. NetBeans so verkorkste Strukturen aufbaut, damit man ein paar Controls anlegen kann.

Ich poste jetzt hier jetzt mal meine Version:

```
/**
   * Überprüft die Pflichtfelder.
   * @param container Container, der die zu überprüfenden Controls enthält.
   * @param pflichtfelder Namen der Controls, die überprüft werden sollen.
   * Zur Überprüfung ist es erforderlich, dass die Eigenschaft name aller
   * Controls gesetzt wird.
   * @return Liefert das erste Pflichtfeld zurück, wenn es nicht gefüllt wurde
   */
  private Component pruefePflichtfelder(Container container, 
                                        String[] pflichtfelder) {
    Component ergebnis = null;
    int n = container.getComponentCount();
    
    for (int i = 0; i < n && ergebnis == null; i++) {
      Component component = container.getComponent(i);
      // Nur aktive Komponenten holen
      if (component.isEnabled()) {
        if (component instanceof JTextField) {
          JTextField textField = (JTextField) component;
          // Nur editierbare, leere Textfelder holen
          if (textField.isEditable() 
              && 0 == textField.getText().trim().length()) {
            for (int j = 0; j < pflichtfelder.length 
                && ergebnis == null; j++) {
              if (pflichtfelder[j].equals(textField.getName())) {
                ergebnis = textField;
              }
            }
          }
        } else if (component instanceof Container) {
           // Container rekursiv durchgehen
           ergebnis = pruefePflichtfelder((Container) component, 
               pflichtfelder);
        }
        // Alle anderen Komponenten ignorieren
      }
    }
    return ergebnis;
  }
```
Und so erfolgt der Aufruf:

```
pflichtControl = pruefePflichtfelder((Container) this.getComponent(0), new String[] {"Mitgliedsnummer"});
```


----------



## Toast78 (2. Jan 2007)

Aaaarg! Ich bekomm die Krise! Funktionieren tut das ganze ja. Nur werden die Controls nicht in der Reihenfolge abgearbeitet, in der sie auch erstellt wurden.


----------



## WieselAc (2. Jan 2007)

Die Reihenfolge hängt vom layout und von der Reihenfolge in der sie geadded wurden ab.


----------



## Toast78 (2. Jan 2007)

Und wie stell ich die Aktivierungsreihenfolge ein?


----------



## WieselAc (2. Jan 2007)

Einstellen kannst du das garnicht. Entweder du weißt in welcher reihenfolge du die Componenten geaddet hast, oder du musst dir einen komplett anderen Mechanismus überlegen (z.B eine Liste mit allen komponenten anlegen, verschachtelten check aufruf, etc...)


----------



## Toast78 (2. Jan 2007)

Ich bedanke mich auch bei dir für deine Hilfe. 

Dann doch lieber klickibunti MS-Access*. Ich weiß nicht, was die Leute an Microsoft-Produkten auszusetzen haben. Wenn ich so einen Scheiß sehe, könnte ich echt kotzen.

*Dummerweise ist der Teufel ein Eichhörnchen.


----------



## WieselAc (2. Jan 2007)

nana wer wird sich den gleich aufregen, beim nächstenmal einfach direkt die Programmstruktur dementsprechend entwerfen und schon gehts


----------



## Toast78 (2. Jan 2007)

So als Konsolensprache gehts ja. Nur ab der GUI-Programmierung wird Java, sagen wir, doch ein bisschen holprig. Schon allein was die Zuverlässigkeit des GUI-Editors betrifft.


----------



## Guest (2. Jan 2007)

```
List<JTextField> list = new ArrayList<JTextField>();
collectEmptyFields( container, list );
Collections.sort(list, irgendeinComparatorDerDieRichtigeReihenfolgeSicherstellt);

// und Akschn
```


----------



## Toast78 (2. Jan 2007)

@Unbekannter Gast: irgendeinComparatorDerDieRichtigeReihenfolgeSicherstellt
Haha, wie soll denn so ein Comparator aussehen? ???:L Mit Verlaub, aber wie soll man denn Controls von einander unterscheiden können, wenn nicht von ihrem Namen? Und dass die Controls nicht alphabetisch nach ihren Namen geordnet sind, kann MANCHMAL vorkommen. Zumal, ich will nicht irgend eine Liste abackern. Ich möchte das erste Control haben, das leer ist. Schließlich habe ich ja auch nur einen Fokus. Was sollte ich dann also mit den einer Liste von leeren Controls anfangen?

@WieselAC: Also ich habe vorhin mal die einzelnen JPanels (ich habe zusammengehörige Textfelder in einm JPanel zusammengefasst) mittels Sicherheitskopie rausgelöscht und wieder reinkopiert. Nur für ein Textfeld funktionierte das bisher nicht. Also habe ich die Textfelder aus diesem JPanel rausgeschmissen und dann wieder neu erstellt. Funktioniert immer nocht nicht. Dabei habe ich auch im Kontext-Menü den Eintrag "Change Order..." enthalten, aber auch dort war die Reihenfolge so eingestellt, wie ich sie gern hätte.


----------

