Search code examples
javaswingreflectionjtextfieldgettext

java.lang.reflect.field getText when field is JTextfield


I have a class with over 50 JTextfield they all contain text

How to get the text from all Textfield without calling the fields in the code again.

I tried:

    Field[] fields = getClass().getDeclaredFields();       
    for (Field field : fields) {        
        if (field.getName().contains("_") == true) {
            // .getText();
        }
    }

Then I must get the text from the fields but how to manage this??

Or have someone a better idea to the the values??


Solution

  • As Hovercraft Full Of Eels suggested, a clean implementation separates the matter : grouping fields gather and performing a processing on them. Especially, if grouping is performed by reflection.
    The following code is more readable and maintainable.

    public class MyComponent extends JFrame{
      List<JTextField> fields = new ArrayList(); 
    
      private JTextField textField1;
      private JTextField textField2;
      private JTextField textField3;
    
      public MyComponent(){
       textField1 = new JTextField ("");
       textField2 = new JTextField ("");
       textField3 = new JTextField ("");
       addTextFieldInList(textField1, textField2, textField3);
      }
    
      public void addTextFieldInList(JTextField fieldArgs...) {
        fields.addAll(Arrays.asList(fieldArgs));
      }
    
      public void iterateAllTextFields(){
        for (JTextField field : fields){
          String yourValue = field.getText();
        }    
    }
    

    UPDATE after the update of the question where it is specified that the processing handle more than over 50 JTtextField.

    In this case, another solution that which I proposed could be more suitable. Indeed, with a dozen of fields, risking to forget to add a JTextField in the list is not very probable but with over 50, we can understand that is a error-prone processing. Creating your custom JTextField is maybe a better alternative. The idea is the following : extending the JTextField with a new class JTextFieldWatched and forcing JTextFieldWatched constructor with an additional parameter : a object which registers JTextField instances.

    JTextFieldWatched which extends JTextField :

    public class JTextFieldWatched extends JTextField{
      public JTextFieldWatched(String text, JTextFieldWatcher textFieldWatcher){
        super(text);
        if (textFieldWatcher==null){
          // force the constraint
          throw new IllegalArgumentException("textFieldWatcher is mandatory");
        }        
         textFieldWatcher.add(this);
      }
    }
    

    A class which registers JTextfield instances :

    public class JTextFieldWatcher {
       List<JTextField> fields = new ArrayList(); 
    
       public void add(JTextField textField){
          fields.add(textField);
       }   
    
       public List<JTextField> getAllTextField(){
          return new ArrayList(fields);
       }
    }
    

    How to use these classes:

    public class MyComponent extends JFrame{
      private JTextFieldWatcher fieldsWatcher = new JTextFieldWatcher();
    
      private JTextFieldWatched textField1;
      private JTextFieldWatched textField2;
      private JTextFieldWatched textField3;
    
      public MyComponent(){
       textField1 = new JTextFieldWatched ("",fieldsWatcher);
       textField2 = new JTextFieldWatched ("",fieldsWatcher);
       textField3 = new JTextFieldWatched ("",fieldsWatcher);
      }   
    
      public void iterateAllTextFields(){
        for (JTextField field : fieldsWatcher.getAllTextField()){
          String yourValue = field.getText();
        }    
      }
    }
    

    All code is written at the hand without IDE, so sorry if any mistake.