Bedingungen abkürzen

Escape99X

Mitglied
Hallo,
ich habe folgendes Problem:
Ich habe ein Fenster, in dem einige Textfelder sind, in die Text eingetragen werden soll.
Wenn alle Felder ausgefüllt wurden soll ein speichern-Button auf setEnabled(true) gesetzt werden.
Dies wollte ich mit einem KeyListener erreichen, der aufgerufen wird, wenn in eines der Felder geschrieben wird:
Java:
private class KeyEventClass extends JFrame implements KeyListener {
        public void keyTyped(KeyEvent e) {}
        public void keyPressed(KeyEvent e) {}
        public void keyReleased(KeyEvent e) {}
}
public static void main(String[] args) {
        tfNachname.addKeyListener(new KeyEventClass());
        tfVorname.addKeyListener(new KeyEventClass());
        tfStrasse.addKeyListener(new KeyEventClass());
        tfNummer.addKeyListener(new KeyEventClass());
        tfOrt.addKeyListener(new KeyEventClass());
        tfIban.addKeyListener(new KeyEventClass());
        tfBetrag.addKeyListener(new KeyEventClass());
        tfVerwendung.addKeyListener(new KeyEventClass());
}
Jetzt möchte ich in dem Keylistener abfragen, ob alle Einträge leer sind:
Java:
if(tfNachname.getText().equals(null) || tfVorname.getText().equals(null) || tfStrasse.getText().equals(null) || ...){}
Ist es möglich diese Bedingung zu verkürzen?
Oder kennt jemand eine andere Möglichkeit, den Button zu aktivieren, wenn alle Textfelder ausgefüllt sind?
Vielen Dank für eure Unterstützung
 
Jein, die Bedingungen an sich kann man nicht mehr kürzen.
Die Anzahl der Bedingungen kann man aber noch reduzieren: Alle Textfield in eine Liste geben und darüber iterieren + und jedes testen ob leer.

Eine andere Möglichkeit wäre mit Hilfe des ButtonModel und Documents zu arbeiten 😉
Im Grunde wird dort auch nur mit einer Liste + Schleife gearbeitet: http://stackoverflow.com/questions/23856818/set-enable-button-if-text-field-is-fill

EDIT: Hier eine Variante
Java:
public boolean isFilled(JTextfield... args) {
   for(int i = 0; i < args.length; i++) {
     if(args[i].getText().equals(null)) {
       return false;
     }
   }
   return true;
}

...
if(isFilled(tfNachname, tfVorname, tfStrasse, ...)) {
 
Zuletzt bearbeitet:
Reflection wäre auch noch ein Möglichkeit, um an die "Member" einer Klasse zu gelangen, und Methoden aufzurufen.
 
Java:
/*
* Methode checkt ob ein Feld ausgefüllt wurde
*/
public boolean checkSingleField(String in){
  String s = in.trim();
  return !in.isEmpty();
}

würde ich machen......diese Methode kannst du dann ich eine weitere stecken die alle Felder prüft....
 
Okay, besonders schön ist es jetzt nicht, aber:
Java:
/**
 * @author DerWissende on 03/25/2016
 */
public class TextFields {

    public JTextField textField1 = new JTextField();
    public JTextField textField2 = new JTextField();
    public JTextField textField3 = new JTextField();
    public JTextField textField4 = new JTextField();
    // ... weitere TextFields hinzufuegen ...
    public JButton button1 = new JButton("Action Button");

    public TextFields() throws IllegalAccessException {
        JFrame jf = new JFrame("TextFields Demo");
        final Field[] fa = this.getClass().getFields();
        jf.setLayout(new GridLayout(fa.length, 1));
        for (Field f : fa) {
            jf.add((Component) f.get(this));
        }
        for (Field f : fa) {
            if (f.getName().contains("textField")) {
                JTextField tf = (JTextField) f.get(this);
                tf.addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyTyped(KeyEvent e) {
                        try {
                            for (Field f : fa) {
                                if (f.getName().contains("textField")) {
                                    JTextField tf = (JTextField) f.get(TextFields.this);
                                    String text = tf.getText();
                                    if (text == null || text.isEmpty()) {
                                        return;
                                    }
                                }
                            }
                            System.out.println("a");
                        } catch (IllegalAccessException iaex) {
                            iaex.printStackTrace();
                        }
                    }
                });
            }
        }

        jf.setSize(600, 143);
        jf.setDefaultCloseOperation(2);
        jf.setVisible(true);
    }

    public static void main(String[] args) throws IllegalAccessException {
        new TextFields();
    }
}

Es können weitere JTextField's hinzugefügt werden, sie müssen nur textFieldX heißen.
 
Man könnte auch über die via getComponents ermittelten Komponenten iterieren, mit instanceof auf JTextField prüfen, in eine JTextField-Variable casten und dann die Abfrage machen. Falls sich die Textfelder über mehrere evtl verschachtelte Container verteilen, müsste man das allerdings rekursiv machen oder die Prüfung pro Container einzeln aufrufen.
 
Ich meinte doch, an der ein oder anderen Stelle ist das etwas wirr. Über getComponents ermitteln/iterieren gefällt mir neben JTextField-Array sehr gut. Ein (scheinbarer) Nachteil hat die Reflection-Möglichkeit auch, die Felder müssen public sein und es sollte neben Components keine anderen Felder geben. instanceof könnte man auch in der Schleife benutzen, dann braucht man einen (speziellen) Namen gar nicht. Naja, es war auch nur eine "Demo", wie es mit Reflection hätte funktionieren können.
 
Naja, es war auch nur eine "Demo", wie es mit Reflection hätte funktionieren können.
Jeder Ansatz hat Vor- und Nachteile. Man muss eben abwägen, was für den Anwendungsfall am besten geeignet ist. Mir scheint der Ansatz von Joose in der Regel der pragmatischste zu sein, denn meistens benötigt man ja ohnehin noch individuelle Prüfungen pro Feld und möchte einzelne Felder von der isEmpty-Prüfung ausnehmen. Für so etwas könnten unsere beiden Ansätz etwas zu behäbig sein. Und für richtig große Anwendungen mit sehr vielen Feldern wird man die Prüfungen vermutlich ohnehin in irgendeine Art von konfigurierbarem Data-Dictionary auslagern.
 
Noch mal etwas abgeändert:
Java:
public class TextFields {

    public JTextField textField1 = new JTextField();
    public JTextField textField2 = new JTextField();
    public JTextField textField3 = new JTextField();
    public JTextField textField4 = new JTextField();
    // ... weitere TextFields hinzufuegen ...
    public JButton button1 = new JButton("Action Button");

    public TextFields() throws IllegalAccessException {
        JFrame jf = new JFrame("TextFields Demo");
        Component[] compo = getCompo();
        jf.setLayout(new GridLayout(compo.length, 1));
        for (Component c : compo) {
            jf.add(c);
        }
        final JTextField[] textF = getTextF();
        for (JTextField tf : textF) {
            tf.addKeyListener(new KeyAdapter() {
                @Override
                public void keyTyped(KeyEvent e) {
                    for (JTextField tf : textF) {
                        String text = tf.getText();
                        if (text == null || text.isEmpty()) {
                            return;
                        }
                    }
                    System.out.println("a");
                }
            });
        }

        // Resizen
        jf.setDefaultCloseOperation(2);
        jf.setVisible(true);
    }

    public Component[] getCompo() throws IllegalAccessException {
        // Reflection
    }

    public JTextField[] getTextF() throws IllegalAccessException {
        // Reflection
    }

    public static void main(String[] args) throws IllegalAccessException {
        new TextFields();
    }
}

Jedesmal, wenn "a" ausgegeben wird, sind alle Eingaben gültig. 😱

instanceof hat mir weitergeholfen.

Edit: Aber nebenbei ist mir aufgefallen, Reflection über alle Fields und instanceof ist ziemlich langsam und träge, also das Gelbe vom Ei ist das noch nicht.
 
Reflection über alle Fields und instanceof ist ziemlich langsam
Wenn ich deinen Code richtig verstehe gehst du ja auch bei jedem Tastendruck über alle Textfelder und prüfst. Wäre es nicht sinnvoller bei einem Tastendruck nur den Status des aktuellen Textfeldes zu überprüfen und in einer Variablen (boolean Array oder so) sich zu merken ob alle Textfelder nicht leer sind und nur dieses im EventListener dann zu überprüfen um den Button auf enabled zu setzen ?
 
Wow bitte doch keine Reflections. Versuchs doch mal mit den richtigen Werkzeugen. Hier ein kleines Beispiel:
Java:
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class Test {
  
  public static void main(String... args) {
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        new Test();
      }
    });
  }
  
  public Test() {
    JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationByPlatform(true);
    
    JPanel mainPanel = new JPanel(new GridLayout(4, 1));
    
    JButton allFill = new JButton("All filled");
    allFill.setEnabled(false);
    allFill.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        frame.dispose();
      }
    });
    
    JTextField[] fields = new JTextField[3];
    for (int i = 0; i < fields.length; i++) {
      fields[i] = new JTextField(20);
      fields[i].getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void removeUpdate(DocumentEvent e) {
          allFill.setEnabled(isAllFilled(fields));
        }
        
        @Override
        public void insertUpdate(DocumentEvent e) {
          allFill.setEnabled(isAllFilled(fields));
        }
        
        @Override
        public void changedUpdate(DocumentEvent e) {
          allFill.setEnabled(isAllFilled(fields));
        }
      });
      mainPanel.add(fields[i]);
    }
    mainPanel.add(allFill);
    
    frame.add(mainPanel);
    frame.pack();
    frame.setVisible(true);
  }
  
  private boolean isAllFilled(JTextField[] fields) {
    for (JTextField field : fields) {
      if (field.getText() == null || field.getText().isEmpty()) {
        return false;
      }
    }
    return true;
  }
  
}
 

Neue Themen


Zurück
Oben