Pagina 2 di 2 primaprima 1 2
Visualizzazione dei risultati da 11 a 17 su 17

Hybrid View

  1. #1
    ciao andbin!

    innanzitutto, buon natale (anche se ormai è passato)!

    prendendo il primo punto, relativo ai genercis.
    mi sono letto parecchi esempi, ma non sono riuscito a capire come applicarlo al mio caso.
    io ho due metodi che hanno la stessa logica, e che solo due differenze:
    -il file da cui leggono
    -il tipo di lista che creano (ArrayList<Author> o ArrayList<Editor>)

    volendo fare un unico meteodo generico:
    -il file glielo potrei passare come parametro
    -dovrei creare una lista generica -> ma qua mi sorgono delle domande
    banalmente ho fatto una prova del genere (per capire un pò meglio di che parliamo), ma da errore:
    codice:
        public List<?> getAllAuthorsEditors(String fileJson) throws IOException {
            File file = new File(fileJson);
            List<?> list = new ArrayList<>();
            if (file.exists()) {
                Gson gson = new Gson();
                JsonParser parser = new JsonParser();
                try (BufferedReader bf = new BufferedReader(new FileReader(file))) {
                    JsonArray jarray = parser.parse(new JsonReader(bf)).getAsJsonArray();
                    for (JsonElement e : jarray) {
                        Author au = gson.fromJson(e, Author.class);
                        list.add(new Author(au.id, au.name));
                    }
                }
            }
            return list;
        }
    e cmq non è molto generalizzato, perchè Author glielo impongo nel metodo, quindi sarei di nuovo da capo.

    ho visto che potrei creare una classe generica di questo tipo:
    codice:
    public class AEContainer<T> {
    
        private T t;
    
        public void add(T t) {
            this.t = t;
        }
    
        public T get() {
            return t;
        }
    }
    ma cmq non riesco ad usarla applicato al mio esempio.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    innanzitutto, buon natale (anche se ormai è passato)!
    Ciao, buone feste!

    Quote Originariamente inviata da fermat Visualizza il messaggio
    prendendo il primo punto, relativo ai genercis.
    mi sono letto parecchi esempi, ma non sono riuscito a capire come applicarlo al mio caso.
    Ecco l'indizio.

    Innanzitutto rendi "generica" la tua classe del frame base, dichiarando una type variable <T> che ti servirà per svariate cose: per parametrizzare il JComboBox, per il parametro di riempiCombo, per altro ....
    Poi all'atto della estensione per le due sottoclassi, andrai a fissare la parametrizzazione concreta. Questo ti permetterà di fare tutto in modo assolutamente type-safe, senza bisogno di <?> o <? extends Xyz> o cose del genere.

    Riguardo il metodo di lettura del JSON effettivamente è un po' diverso/complicato. Lì servono due cose particolari:
    - un "class token", ovvero un oggetto Class.
    - la invocazione di un costruttore ben specifico (non puoi fare new T() con T una type variabile, non è lecito)

    Tra l'altro (domanda, curiosità mia): visto che il fromJson ti fornisce già un oggetto Author (o Editor), perché poi ne istanzi un altro? Non ti basta quello deserializzato dal JSON??

    Comunque si può risolvere e anche bene. Per il momento valuta l'indizio sopra.
    Se l'indizio non è sufficiente ... vado con del codice.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Ok, ecco un indizio più grosso.

    codice:
    public class FrameBase<T> extends JInternalFrame {
        private JComboBox<T> comboUp;
    
        //....
    
        protected void riempiCombo(List<T> list) {
            // .....
        }
    }
    codice:
    public class FrameAuthor extends FrameBase<Author> {
        //....
    }

    Inizi a vedere i benefici di tutto questo?


    Invece per quanto riguarda il metodo che legge/deserializza il JSON, visto che è un concetto trasversale, cioè che può essere utile in più parti della tua applicazione, ti conviene fare una classe a parte che sia in grado di gestire qualunque tipo di classe.
    Qualcosa del tipo:

    codice:
    public class JsonIO {
        private Gson gson;
    
        //....
    
    
        public <T> List<T> readArray(File file, Class<T> type) throws ..... {
            //....
        }
    }

    Presupponendo però che non devi invocare esplicitamente il costruttore di Author/Editor (che secondo me non ti serve).

    Nella classe FrameAuthor lo puoi usare:

    codice:
    private JsonIO jsonIO = new JsonIO();
    
        ...
        List<Author> listaAutori = jsonIO.readArray(new File(UrlAndPath.JSON_AUTORI), Author.class);
        riempiCombo(listaAutori);
    Ultima modifica di andbin; 27-12-2015 a 12:58
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    ciao andbin!
    grazie mille per l'esempio!

    sul discorso classe base e classe estesa, ci ero più o meno arrivato.
    codice:
    public class FrameAEBase<T> extends JInternalFrame {
        protected void riempiCombo(List<T> list) {
            comboUp.removeAllItems();
            comboUp.addItem("*");
            list.stream().forEach((strObj) -> {
                comboUp.addItem(strObj);
            });
        }
    }
    codice:
    public class FrameAuthor extends FrameAEBase<Author> {
    
        private ReadJson jsonRead = new ReadJson();
        private List<Author> list = null;
    
        public FrameAuthor() {
            super();
            super.setTextButtonAdd("Aggiungi autore");
            super.setTextButtonUp("Modifica autore");
            super.setTextButtonDel("Cancella autore");
            try {
                list = jsonRead.getAllAuthorsEditors(UrlAndPath.JSON_AUTORI, Author.class);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage());
            }
            super.riempiCombo(list);
        }
    }
    devo finire di sistemarlo.

    sull'altro discorso, invece, avevo un buco totale.
    ora prendo il tuo esempio ci lavoro.
    appena finisco posto il risultato!!

  5. #5
    arieccomi.
    purtroppo mi sono ribloccato.
    mi manca un pezzo che non riesco a capire.
    partendo dall'internal frame:
    codice:
    public class FrameAuthor extends FrameAEBase<Author> {
    
        private ReadJson jsonRead = new ReadJson();
        private List<Author> list = null;
    
        public FrameAuthor() {
            super();
            setTextButtonAdd("Aggiungi autore");
            setTextButtonUp("Modifica autore");
            setTextButtonDel("Cancella autore");
            try {
                list = jsonRead.getAllAuthorsEditors(UrlAndPath.JSON_AUTORI, Author.class);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage());
            }
            riempiCombo(list);
        }
    }
    fin qui ok.
    ora, il problema sta sul metodo getAllAuthorsEditors (quello che tu avevi nominato come readArray in sostanza).
    questo è quello che ho scritto:
    codice:
        public <T> List<T> getAllAuthorsEditors(String fileJson, Class<T> type) throws IOException {
            File file = new File(fileJson);
            List<T> list = new ArrayList<>();
            if (file.exists()) {
                Gson gson = new Gson();
                JsonParser parser = new JsonParser();
                try (BufferedReader bf = new BufferedReader(new FileReader(file))) {
                    JsonArray jarray = parser.parse(new JsonReader(bf)).getAsJsonArray();
                    for (JsonElement e : jarray) {
                        Class<T> cls = gson.fromJson(e, type.getClass()); // --> ECCEZIONE
    //                    list.add(cls.cast(e));
                    }
                }
            }
            return list;
        }
    ottengo una eccezione alla riga commentata.
    questa è l'eccezione:
    codice:
    Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: Attempted to deserialize a java.lang.Class. Forgot to register a type adapter?
        at com.google.gson.internal.bind.TypeAdapters$1.read(TypeAdapters.java:77)
        at com.google.gson.internal.bind.TypeAdapters$1.read(TypeAdapters.java:61)
        at com.google.gson.Gson.fromJson(Gson.java:803)
        at com.google.gson.Gson.fromJson(Gson.java:868)
        at com.google.gson.Gson.fromJson(Gson.java:841)
        at com.mp.book.ReadJson.getAllAuthorsEditors(ReadJson.java:51)
    .............................................
    mi pare di capire che il problema derivi dal fatto che Gson non è in grado di capire di quale classe si tratti.
    pensavo, però, di avergliela impostata con type.getClass().
    non riesco a capire se sbaglio qui, o nell'internal frame!

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Non ci siamo. Tra l'altro ti consiglio di separare la logica "generica" di parsing del JSON dalla tua logica applicativa specifica (il fatto che se il file non esiste la lista la consideri vuota è una tua logica applicativa).

    Quindi una cosa tipo:

    codice:
    // .... gli import ....
    
    public class JsonIO {
        private Gson gson;
    
        public JsonIO() {
            gson = new Gson();
        }
    
        public <T> List<T> readArray(File file, Class<T> type) throws FileNotFoundException, IOException {
            ArrayList<T> list = new ArrayList<T>();
            JsonParser parser = new JsonParser();
    
            try (BufferedReader bf = new BufferedReader(new FileReader(file))) {
                JsonArray jsonArray = parser.parse(new JsonReader(bf)).getAsJsonArray();
    
                for (JsonElement jsonElement : jsonArray) {
                    T element = gson.fromJson(jsonElement, type);
                    list.add(element);
                }
            }
    
            return list;
        }
    }

    Poi nella classe base dei frame:

    codice:
    private JsonIO jsonIO;
    
    protected <T> List<T> readAllItems(String fileJson, Class<T> type) throws FileNotFoundException, IOException {
        File file = new File(fileJson);
        List<T> list;
    
        if (file.exists()) {
            list = jsonIO.readArray(file, type);
        } else {
            list = new ArrayList<T>(0);
        }
    
        return list;
    }

    E infine in ciascuna classe specifica, banalmente:

    codice:
    list = readAllItems(UrlAndPath.JSON_AUTORI, Author.class);

    Molto buttato lì, eh. Devi anche valutare bene tutte le eccezioni possibili, dove/come gestirle ecc...
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    ok penso di aver capito meglio.
    in sostanza:
    - una classe con un metodo che si occupa di fare il parsing del json, al quale passo i dati generici (in modo da non replicare nessuna logica)
    - nel frame (eventualmente un frame base come in questo caso) richiamare quella classe/metodo, ed poi usare i dati (riempire jtbale, jcombobox, ecc); qui fare anche eventuali controlli (ad esempio esistenza del file)
    - in eventuali sotto-classi (come in questo caso) richiamare i metodi generici della super-classe, passando i parametri specifici
    - intercettazioni eventuali eccezioni, generalmente le faccio nei vari frame, lanciando degli jotpionpane

    se così è, devo mettere a posto un bel di cose

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.