【问题标题】:java.lang.reflect.field getText when field is JTextfield当字段为 JTextfield 时 java.lang.reflect.field getText
【发布时间】:2016-11-06 19:37:38
【问题描述】:

我有一个超过 50 个 JTextfield 的类,它们都包含文本

如何在不再次调用代码中的字段的情况下从所有Textfield中获取文本。

我试过了:

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

那么我必须从字段中获取文本,但是如何管理呢?

或者有人对这些价值观有更好的想法??

【问题讨论】:

  • 至少可以说这是一个非常糟糕的程序设计。为什么不将这些字段放在一个集合中,以便您可以识别需要从中提取文本的字段?
  • 您的问题表明这实际上可能是XY Problem,您在其中询问如何解决特定代码问题,而最佳解决方案是使用完全不同的方法。最好告诉我们您正在尝试解决的总体问题,而不是您当前尝试解决的方式。
  • @JonnyHenly:你说得对,谢谢!不过,他为什么要使用反射?为什么他如此重视字段名称?
  • Abgebaumt:请告诉并展示更多信息。一定有比你正在做的更好的方法。我会在这上面赌 100 美元。
  • @Abgebaumt:再次,请编辑您的问题,并将此信息添加到其中以及有关 50 个字段的更多信息,它们是如何组织和显示的。这些信息太重要了,不能被埋在 cmets 中。此外,反射既不干净也不,速度也不快,并且保证不是最好的方法。它也很脆弱,如果您或其他人在以后重命名某个字段,它会损坏。同样,我可以保证存在更好的解决方案。既然你提到了 50 个 JTextFields,我不得不怀疑 JTable 是否会更好,但如果没有更多信息,我又不能说。

标签: java swing reflection jtextfield gettext


【解决方案1】:

正如 Hovercraft Full Of Eels 所建议的那样,一个干净的实现将事情分开:分组字段收集并对其执行处理。 特别是,如果通过反射执行分组。
以下代码更具可读性和可维护性。

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();
    }    
}

在指定处理超过50个JTtextField的问题更新后更新。

在这种情况下,我提出的另一种解决方案可能更合适。 确实,有十几个字段,冒着忘记在列表中添加 JTextField 的可能性不大,但超过 50 个,我们可以理解这是一个容易出错的处理。创建您的自定义 JTextField 可能是一个更好的选择。 想法如下:使用新类 JTextFieldWatched 扩展 JTextField 并使用附加参数强制 JTextFieldWatched 构造函数:注册 JTextField 实例的对象。

JTextFieldWatched 扩展 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);
  }
}

注册JTextfield实例的类:

public class JTextFieldWatcher {
   List<JTextField> fields = new ArrayList(); 

   public void add(JTextField textField){
      fields.add(textField);
   }   

   public List<JTextField> getAllTextField(){
      return new ArrayList(fields);
   }
}

如何使用这些类:

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();
    }    
  }
}

所有代码都是在没有IDE的情况下编写的,如果有任何错误,请见谅。

【讨论】:

  • 不,谢谢你。所有问题都不一定按照要求的方式解决。特别是,如果这种方式看起来很笨拙。
  • 通常我更喜欢自己给出“其他”答案(因为总是有人给出直接的“答案)......但我很高兴你也提出了你的建议!
  • @GhostCat,我知道。我有时想知道同样的问题:花时间与否......
  • 我试过了,效果很好。非常感谢
【解决方案2】:

您可以使用反射来确定字段的实际类型,例如:

Field[] fields = getClass().getDeclaredFields();       
for (Field field : fields) {  
    Class<?> fieldType = field.getType();
    if (fieldType.isAssignableFrom(JTextfield.class)) {
      JTextField jtf = (JTextField) field.get(owningobject);       
 ...

换句话说:

  1. 您可以检查该字段是否“是”一个 JTextField(这很多比依赖某些约定,即名称中带有“_”的任何内容都是一个文本字段)
  2. 如果是这样,您只需获取该字段的值,并将其转换为它的真实类型...然后,您将获得一个 JTextField 对象,您可以调用该类的方法直接!

请注意:我的代码是为了让您继续前进 - 我没有通过编译器运行它或测试它。所以,谨防错别字。但这应该足以让您自己进行实验并帮助您取得进步。

编辑,关于您的问题:所有这些反射 get/set 方法都需要您一些对象来处理。含义:您需要一个您正在“反映”的类的实例(除非您在谈论静态字段)。请参阅here 或there 进一步阅读。

警告的最后一句话;因为在使用反射时您应该知道 两件事:

  1. 只有在没有其他方法可以解决您的问题时才使用它。永远不要使用它,因为它看起来很方便,但因为没有其他方法可以满足您的需求!
  2. 只有在你理解 100% 的反射时才使用它。问题是:反射错误是超级容易。而且您只会在运行时注意到。您可以轻松地花费数小时编写反射代码并尝试使其工作;从一个微妙的问题跑到下一个问题。获取反射代码是困难。更痛苦的是:“被反射”的代码中的细微变化可能破坏您使用反射的代码;在运行该代码之前您不会注意到!

所以,长话短说,鉴于您的问题:您似乎不对反射了解很多。从这个意义上说:要非常小心。并且也许重新考虑是否有其他非反思的方法来解决您的问题!

【讨论】:

  • Ghost:虽然这可行,但它是否干净,而且这种设计没有代码味道吗?
  • 你能帮帮我吗?在“拥有对象”中放置什么
  • 我更新了我的答案。并提示:请耐心等待。是的,人们愿意提供帮助,但请放心:我第一次看到您的评论。无需反复询问...
  • @HovercraftFullOfEels 阅读他的评论后,我得出了相同的结论并相应地更新了我的答案。
  • 幽灵,谢谢。 @Abgebaumt:什么是“拥有对象”?再次,请在编辑您的原始问题时告诉我们更多有关您的问题空间的信息。帮助提出更好的问题,以便本网站可以得到更好的答案。
猜你喜欢
  • 2013-10-06
  • 1970-01-01
  • 2012-09-24
  • 2013-02-10
  • 2021-05-04
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多