Gson deserialisieren mit PropertyChangeSupport

Fohnbit

Top Contributor
Hallo,

ich lade ein JSON um folgende Klasse zu erstellen:
Java:
public class Product implements InstanceCreator<Product> {
    private transient final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.removePropertyChangeListener(listener);
    }

    public Product() {
        // init
        setCanBeSold(true);
        setCanBePurchased(true);
        setBuy(true);
        setTracking(EnumTracking.none);
    }
    private transient Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").disableHtmlEscaping()
            .create();
    private String productName = "";
    private boolean canBeSold;
    private boolean canBePurchased;


    /**
     * @return the productName
     */
    public String getProductName() {
        return productName;
    }

    /**
     * @param productName the productName to set
     */
    public void setProductName(String productName) {
        this.pcs.firePropertyChange("productName", this.productName, productName);
        this.productName = productName;

    }

    /**
     * @return the canBeSold
     */
    public boolean isCanBeSold() {
        return canBeSold;
    }

    /**
     * @param canBeSold the canBeSold to set
     */
    public void setCanBeSold(boolean canBeSold) {
        this.pcs.firePropertyChange("canBeSold", this.canBeSold, canBeSold);
        this.canBeSold = canBeSold;
    }

...

@Override
    public Product createInstance(Type arg0) {
        return new Product();
    }

When ich nun das JSON lade, feuert mir nicht das "PropertyChangeSupport".

Hierfür habe ich den "InstanceCreator" hinzuegfügt.

Aber wenn ich das JSON lade, feuert mir die Methode "createInstance" nicht.

Mach ich etwas falsch?

Danke!
 

mrBrown

Super-Moderator
Mitarbeiter
Was genau hast du denn vor?

When ich nun das JSON lade, feuert mir nicht das "PropertyChangeSupport".
Mit "JSON laden" meinst du vermutlich, dass du Json zu einem Produkt deserialisierst?

Dann ist es doch logisch, dass keine Events gefeuert werden - das Produkt wird ja in dem Moment erst erstellt, es können also noch keine Listener registriert sein. Genauso wie bei einem Erstellen mit new keine Listener darüber informiert werden können.

Hierfür habe ich den "InstanceCreator" hinzuegfügt.

Aber wenn ich das JSON lade, feuert mir die Methode "createInstance" nicht.

Mach ich etwas falsch?

In jedem Fall ist dieses Konstrukt mit InstanceCreator völliger Unsinn - du bräuchtest ein Produkt, damit dieses Produkt dann ein neues Produkt erstellen kann, wenn es benötigt wird. Außerdem rufst du nur new Product auf, genau das würde GSON auch ohne InstanceCreator machen.




BTW, das gson-Attribut sollte das höchstwahrscheinlich auch raus.
 

Fohnbit

Top Contributor
Hallo mrBrown,

also ich habe eine Form um Produkte anzulegen. Alle Werte halte ich in einer Klasse. Neue Eingaben in der Form werden in die Klasse geschrieben und Änderungen in der Klasse werden über die PropertyChangeSupport an die Form gemeldet, wo ich die Felder aktualisiere.

Ich speichere das Produkt, das über die Form eingebenen werden, als JSON.

Nun möchte ich aber natürlich auch wieder Produkte laden und lade das JSON und deserialisiere in die Klasse.

Nun muss aber nach dem deserialisieren die Form aktualisiert werden. Ich möchte nicht alle einzeln aktualisieren und hoffte das die neuen Werte in der Klasse Produkt den "PropertyChangeSupport" feuert und ich den neuen neuen Wert in die Form bekommen.

Dann arbeitet die bereits vorhandene Methode um die einzelnen Felder der Form zu aktualisieren
 

mrBrown

Super-Moderator
Mitarbeiter
Alle Werte halte ich in einer Klasse [...] Änderungen in der Klasse [...] deserialisiere in die Klasse [...] in der Klasse Produkt
Du meinst jeweils Objekt, nicht Klasse ;)

Nun möchte ich aber natürlich auch wieder Produkte laden und lade das JSON und deserialisiere in die Klasse.

Nun muss aber nach dem deserialisieren die Form aktualisiert werden. Ich möchte nicht alle einzeln aktualisieren und hoffte das die neuen Werte in der Klasse Produkt den "PropertyChangeSupport" feuert und ich den neuen neuen Wert in die Form bekommen.

Dann arbeitet die bereits vorhandene Methode um die einzelnen Felder der Form zu aktualisieren

Deserialisiere das JSON, dann hast du ein Product, und mit diesem product kannst du dann entweder das andere, bereits an die Form gebundene Produkt aktualisieren, oder das neue Produkt an die Form binden.

Du muss an keiner Stelle direkt in irgendein bestehendes Produkt deserialisieren (das ginge allerdings auch mit InstanceCreator - du müsstest darin nur immer das eine Product zurückgeben, was bereits an die Form gebunden ist, und niemals ein neues Produkt erstellen).
 

Fohnbit

Top Contributor
Guten Morgen mrBrown,

danke für deine Hilfe .. ja Objekt nicht Klasse :)

Also bei mir sieht das gekürzt so aus:
Java:
public class Product {
    private transient final PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.removePropertyChangeListener(listener);
    }

    private String productName = "";
    private boolean canBeSold;
    private boolean canBePurchased;

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.pcs.firePropertyChange("productName", this.productName, productName);
        this.productName = productName;

    }

    public boolean isCanBeSold() {
        return canBeSold;
    }

    public void setCanBeSold(boolean canBeSold) {
        this.pcs.firePropertyChange("canBeSold", this.canBeSold, canBeSold);
        this.canBeSold = canBeSold;
    }

    public boolean isCanBePurchased() {
        return canBePurchased;
    }

    public void setCanBePurchased(boolean canBePurchased) {
        this.pcs.firePropertyChange("canBePurchased", this.canBePurchased, canBePurchased);
        this.canBePurchased = canBePurchased;
    }
}

Die Form Klasse:
Java:
public class Main implements PropertyChangeListener, ActionListener {
    public static Product product = new Product();
    
....

        txtProductName = new JTextField();
        txtProductName.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent arg0) {
                product.setProductName(txtProductName.getText());
            }
        });

        chkCanBeSold = new JCheckBox("Kann verkauft werden");
        chkCanBeSold.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                product.setCanBeSold(chkCanBeSold.isSelected());
            }
        });
       
        chkCanBePurchased = new JCheckBox("Kann eingekauft werden");
        chkCanBePurchased.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                product.setCanBePurchased(chkCanBePurchased.isSelected());
            }
        });

        JMenuItem mnuOpen = new JMenuItem("Öffnen");
        mnuOpen.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

                JFileChooser fileChooser = new JFileChooser();
                if (fileChooser.showOpenDialog(frmProduct) == JFileChooser.APPROVE_OPTION) {
                    JsonReader reader;
                    try {
                        reader = new JsonReader(new InputStreamReader(
                                new FileInputStream(fileChooser.getSelectedFile()), StandardCharsets.UTF_8));

                        Product productTemp = gson.fromJson(reader, Product.class);
                        reader.close();
                        filePath = fileChooser.getSelectedFile();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
        });

...
     /**
     * Listen for changes in the product class
     */
    @Override
    public void propertyChange(PropertyChangeEvent e) {
        System.out.println("Property changed:" + e.getPropertyName());
        Object source = e.getSource();
        if (source == product) {
            switch (e.getPropertyName()) {
            case "productName":
                txtProductName.setText((String) e.getNewValue());
                break;
            case "canBeSold":
                chkCanBeSold.setSelected((boolean) e.getNewValue());
                break;
            case "canBePurchased":
                chkCanBePurchased.setSelected((boolean) e.getNewValue());
                break;
}
 

Ähnliche Java Themen

Neue Themen


Oben