如何在JLabel中显示JTextField的输入?如何修复反射中的错误?

时间:2013-02-02 18:10:46

标签: java swing reflection jlabel jtextfield

我必须这样做:我有一个JTextField和按钮。当我写入TextField时,输出必须在JLabel中显示结果。

  1. 要求用户提供课程名称。
  2. 使用Class.forName()获取对Java Reflection API的访问权。
  3. 使用默认构造函数创建类的新实例(即对象)。
  4. 查找并显示表单中包含继承字段的所有字段:
  5. field_type field_name:(field_value(JTextField))(设置(按钮))

    field_value必须是文本框,以便用户可以通过按“设置”按钮更改值。必须将新值更新为对象。如果该字段包含复杂类型(对象,集合等)的值,则不应创建文本框和“设置”按钮。

    1. 查找并显示该类的所有方法,包括继承的方法: return_type method_name(param_type1(param_value1(JTextField)),param_type2(param_value2(JTextField)),..)(Invoke(Button))
    2. 如果方法具有复杂类型(对象,集合等)的参数,则仅显示参数的类型,跳过param_values的文本框和“调用”按钮。 当用户按下“调用”按钮时,应用程序必须调用该方法。确保如果方法更改字段的值,则会显示这些更改。

      我的代码在这里:

           import java.awt.FlowLayout;
           import java.awt.event.ActionEvent;
           import java.awt.event.ActionListener;
           import java.lang.reflect.Constructor;
           import java.lang.reflect.Field;
           import java.lang.reflect.InvocationTargetException;
           import java.lang.reflect.Method;
           import java.lang.StringBuffer;
           import java.util.Scanner;
           import javax.swing.JButton;
           import javax.swing.JFrame;
           import javax.swing.JLabel;
           import javax.swing.JPanel;
           import javax.swing.JTextField;
      
           public class ReflectionTest {
      
      private String class_name = "java.lang.StringBuffer";
      
      public ReflectionTest() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
          JLabel jl1 = null, jl2, jl3, jl4;
          JFrame jf = new JFrame("New");
          JPanel jp = new JPanel();
           JTextField jtf = new JTextField(20);
           JButton jb = new JButton("Press");
           jtf.setVisible(true);
           jp.add(jb);
           jp.add(jtf);
      
           jf.add(jp);
           jf.setVisible(true);
           jf.setSize(400, 550);
           jf.setResizable(false);
      
      
           String text = jtf.getText().toString();
      
           Class cs = Class.forName(text);
      
           jb.addActionListener(
                      new ActionListener() {
                          public void actionPerformed(ActionEvent e) {
                               // THIS CODE IS EXECUTED WHEN RETURN IS TYPED
                          }
                      }
                  );
      
          for(Constructor c: cs.getConstructors()){
              for(Class p: c.getParameterTypes())
                  System.out.print(p.getName()+" ");
              System.out.println();
          }
      
          Constructor c = cs.getConstructor(new Class[]{String.class});
          Object list = c.newInstance("AA");
      
      
          Field pub_fields[] = cs.getFields();
          Field all_fields[] = cs.getDeclaredFields();
          System.out.println("Public fields:");
          for(Field f:pub_fields){
      
              //Showing public fields
              System.out.println();
              jl1 = new JLabel(f.getType().getName() + " " + f.getName());
              jp.add(jl1);
              jl1.setVisible(true);
                      }
          System.out.println("All declared fields:");
          for(Field f:all_fields){
      
              //Showing all declared fields
      
              jl2 = new JLabel(f.getType().getName() + " "+f.getName()+" ");
              jp.add(jl2);
              jl2.setVisible(true);
      
              f.setAccessible(true);
              Object val = f.get(list);
              if (val != null){
                  //System.out.println(val.toString());
                  jl3 = new JLabel(val.toString());
                  jp.add(jl3);
                  jl3.setVisible(true);
                  System.out.println();
                  }
              else{
                  System.out.println("NULL");
              //f.get(list1);
          }
          }
      
      }
      
      /**
       * @param args
       * @throws ClassNotFoundException 
       */
      public static void main(String[] args) {
          try{
          // TODO Auto-generated method stub
              new ReflectionTest();
          }
          catch (Exception e){
              e.printStackTrace();
          }
      }
        }
      

      我有错误。 Eclipse在这一行显示: 类cs = Class.forName(text);

2 个答案:

答案 0 :(得分:3)

如果在异常发生之前测试文本字符串,例如将其打印出来:

  System.out.printf("text = \"%s\"%n", text);
  Class cs = Class.forName(text);

返回:

text = ""
java.lang.ClassNotFoundException: 
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at pkg.ReflectionTest.<init>(ReflectionTest.java:42)
    at pkg.ReflectionTest.main(ReflectionTest.java:102)

您会看到文本字符串为空,""。这是因为在调用GUI之前调用Class cs = Class.forName(text);时没有文本,因为在渲染GUI之前调用它,更不用说给用户输入文本的时间了。仅在由于某种用户生成的事件(例如ActionListener的actionPerformed方法)而调用的代码中调用此函数。

换句话说,将关键代码添加到您自己的商品中的 ,您声明应该添加代码:

  jb.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent e) {
        // THIS CODE IS EXECUTED WHEN RETURN IS TYPED  // *********!!!!
     }
  });

我在评论中说明你应该显示有关异常的任何和所有信息。请不要让我们猜到问题所在。

修改
此外,在匿名内部侦听器类中使用局部变量(包括JLabel和JTextField)也会遇到问题。解决此问题的最简单和最好的方法是在此侦听器私有类字段中创建需要访问的变量。所以从构造函数中删除它们的声明,而不是将它们移动到类本身。

答案 1 :(得分:2)

真的是错误还是“黄色”线? Class是一个参数化类型,如果你不使用泛型,那么eclipse会显示一个警告。

要消除此类警告,只需执行

即可
Class<?> cs = Class.forName(text);

通配符没问题,因为你真的不知道要加载哪个类的“类型”。