2017-06-17 5 views
0

Ich versuche, Einweg-Datenbindung in Java für Swing-Objekte, nur als Übung. Derzeit füge ich für Swing-Objekte, die JTextComponent erweitern, einen Dokumentlistener hinzu, der auch den Sicherungsdatenspeicher aktualisiert.Field.set wirft 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) { 
    } 
    } 
} 

Das Problem ist, in der folgenden Zeile bekomme ich ein Illegal:

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 

Soweit ich in der Dokumentation sehen, der Aufruf an Field.set korrekt ist. Also verstehe ich nicht, was falsch läuft.

Ich rufe die Funktion mit dem folgenden Code:

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

    } 
} 

Antwort

1

Ich glaube, Sie brauchen Sie den Wert des Schlüssels

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

dataToUpdate.getKey() gibt einen WeakReference zu erhalten, so versuchen, das Feld "Daten" auf eine Instanz von WeakReference zu setzen. Sie möchten das Feld "Daten" für eine Instanz von TestClass festlegen.

+0

Sie haben Recht. Ich weiß nicht, warum ich angenommen habe, dass die Zuweisung durch den SchwachenRef erfolgen kann. Habe es nicht gesehen, erbt ein get(). Vielen Dank. – DebD

Verwandte Themen