2017-06-17 367 views
0

我想在java中为swing对象做单向数据绑定,就像练习一样。目前,对于扩展JTextComponent的swing对象,我添加了一个文档侦听器,它也更新了后备数据存储。Field.set抛出IllegalArgumentException

public class Binder { 

Map<JComponent, Map.Entry<WeakReference, Field>> map = new WeakHashMap<>(); 
AutoDocumentListener adl; 

public Binder() { 
    adl = new AutoDocumentListener(); 
} 

public void bind(Object instance, String varName, JComponent element, String property) { 
    Field field; 
    try { 
     field = instance.getClass().getDeclaredField(varName); 
     field.setAccessible(true); 
     map.put(element, 
       new AbstractMap.SimpleEntry<WeakReference, Field>(new WeakReference(instance), field)); 

     if (element instanceof JTextComponent) { 
      element = (JTextComponent) element; 
      Document eldoc = ((JTextComponent) element).getDocument(); 
      eldoc.putProperty("origin", element); 

      eldoc.addDocumentListener(adl); 
     } else { } 
    } catch (NoSuchFieldException | SecurityException ex) { 
     Logger.getLogger(Binder.class.getName()).log(Level.SEVERE, null, ex); 
    } 
} 

class AutoDocumentListener implements DocumentListener { 

    @Override 
    public void insertUpdate(DocumentEvent evt) { 
     JTextComponent jc = (JTextComponent) evt.getDocument().getProperty("origin"); 
     Map.Entry<WeakReference, Field> dataToUpdate = map.get(jc); 
     if (dataToUpdate != null) { 
      try { 
       Object data = jc.getText(); 
       dataToUpdate.getValue().set(dataToUpdate.getKey(), data); 
      } catch (IllegalArgumentException | IllegalAccessException ex) { 
       Logger.getLogger(Binder.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 
    @Override 
    public void removeUpdate(DocumentEvent evt) { 
    } 
    @Override 
    public void changedUpdate(DocumentEvent e) { 
    } 
    } 
} 

的问题是,在下面的行我得到一个抛出:IllegalArgumentException:

dataToUpdate.getValue().set(dataToUpdate.getKey(), data); 

java.lang.IllegalArgumentException: Can not set java.lang.String field org.jbind.test.TestClass.data to java.lang.ref.WeakReference 

至于我可以在文档看,调用Field.set是正确的。所以,我不明白发生了什么问题。

我打电话用下面的代码功能:

public class TestClass { 
public String data = "Text1"; 

public void init() { 
    Binder binder = new Binder(); 

    JTextField jtf = new JTextField(data); 
    binder.bind(this, "data", jtf, ""); 
    jtf.setText("Text2"); 
    System.out.println(data); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      new TestClass().init(); 
     } 
    }); 

    } 
} 

回答

1

我认为你需要拿到钥匙

dataToUpdate.getValue().set(dataToUpdate.getKey().get(), data); 

dataToUpdate.getKey(值)返回的WeakReference 所以你试图在WeakReference的一个实例上设置“data”字段。你想在TestClass的实例上设置“data”字段。

+0

你是对的。我不知道为什么我认为可以通过WeakRef完成分配。没有看到它继承了get()。谢谢。 – DebD

相关问题