Torna indietro   Hardware Upgrade Forum > Software > Programmazione

realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole!
Hogwarts arriva in fascia media grazie a realme, con una special edition che unisce la Quadra Light-Sensing Color-changing Tech, un baule in stile Hogwarts Express pieno di collezionabili e una scheda tecnica sostanzialmente identica al 16 Pro di partenza: ecco cosa cambia davvero, come si comporta nell'uso quotidiano e quanto vale in base al prezzo di 699,99 euro
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce
REDMI Note 17 Pro porta in fascia media una batteria da 8.340 mAh con ricarica HyperCharge a 67W, un display AMOLED da 6,83 pollici capace di picchi di luminosità molto elevati e una struttura certificata TÜV SÜD contro cadute e infiltrazioni d'acqua, il tutto racchiuso in una scocca da 223 grammi. Lo abbiamo provato per diversi giorni tra fotocamera, prestazioni, autonomia e prezzo sul mercato italiano
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema
Insta360 Luna Ultra integra un sensore da 1 pollice 8K, ottiche Leica e triplo chip IA. Tra schermo OLED rimovibile, workflow I-Log a 10 bit e stabilizzazione a tre assi, analizziamo le doti tecniche di una gimbal camera pensata per i professionisti
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 02-04-2012, 14:48   #1
franksisca
Senior Member
 
L'Avatar di franksisca
 
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
[JAVA] Problema confronto tra due date scritte in JComboBox

allora, ho questa situazione, mi trovo a dover compilare 6 JComboBox che costituiscono due date. il problema è che la seconda data non può mai essere inferiore alla prima.

per il momento ho scritto questo codice:
Codice:
 /**
     *
     * @param giorno1 giorno della prima data
     * @param mese1 mese della prima data
     * @param anno1 anno della prima data
     * @param giorno2 giorno della seconda data
     * @param mese2 mese della seconda data
     * @param anno2 anno della seconda data
     * @return il metodo ritorna true se la prima data è antecedente alla
     * seconda, false altrimenti
     */
    private boolean compare2Dates(String giorno1, String mese1, String anno1, String giorno2, String mese2, String anno2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.set(Integer.parseInt(anno1), Integer.parseInt(mese1), Integer.parseInt(giorno1));
        c2.set(Integer.parseInt(anno2), Integer.parseInt(mese2), Integer.parseInt(giorno2));
        if (c1.before(c2)) {
            return true;//prima data minore della seconda
        } else {
            return false;//seconda data maggiore o uguale della prima
        }
    }
Codice:
 /**
     *
     * da inserire nei changeItemState dei vari comboBox
     */
    private void verificaData() {
        String giorno1 = (String) this.giorniInizio.getSelectedItem();
        String mese1 = (String) this.meseInizio.getSelectedItem();
        String anno1 = (String) this.annoInizio.getSelectedItem();
        String giorno2 = (String) this.giorniScadenza.getSelectedItem();
        String mese2 = (String) this.mesiScadenza.getSelectedItem();
        String anno2 = (String) this.annoScadenza.getSelectedItem();
        if (!(compare2Dates(giorno1, convertiMese(mese1), anno1, giorno2, convertiMese(mese2), anno2))) {
            this.giorniScadenza.setSelectedItem(this.giorniInizio.getSelectedItem());
            this.mesiScadenza.setSelectedItem(this.meseInizio.getSelectedItem());
            this.annoScadenza.setSelectedItem(this.annoInizio.getSelectedItem());
        }
    }
Codice:
 /**
     *
     * @param mese Converte in numero in formato stringa un mese ricevuto in
     * formato stringa
     * @return Ritorna la stringa "1" se il parametro è Gennaio
     */
    private String convertiMese(String mese) {
        if (mese.equalsIgnoreCase("Gennaio")) {
            return "1";
        }
        if (mese.equalsIgnoreCase("febbraio")) {
            return "2";
        }

        if (mese.equalsIgnoreCase("marzo")) {
            return "3";
        }

        if (mese.equalsIgnoreCase("aprile")) {
            return "4";
        }

        if (mese.equalsIgnoreCase("maggio")) {
            return "5";
        }

        if (mese.equalsIgnoreCase("giugno")) {
            return "6";
        }

        if (mese.equalsIgnoreCase("luglio")) {
            return "7";
        }

        if (mese.equalsIgnoreCase("agosto")) {
            return "8";
        }

        if (mese.equalsIgnoreCase("settembre")) {
            return "9";
        }

        if (mese.equalsIgnoreCase("ottobre")) {
            return "10";
        }

        if (mese.equalsIgnoreCase("novembre")) {
            return "11";
        }

        if (mese.equalsIgnoreCase("dicembre")) {
            return "12";
        }
        return "-1";
    }
Poi per ogni changeItemState io richiamo il metodo verificaData(), ma dopo un paio di richiami mi và in java.lang.StackOverflowError.

Cosa potrebbe essere secondo la vostra esperienza? Io penso che ci sia un sovraccarico di richieste e quindi una carenza di risorse...avete metodi alternativi per fare quello che serve a me? Considerate che la struttura delle date non può modificarsi più di tanto....volevo provare ad usare JCalendar ma non credo che implementi in automatico una gestione delle date che possa soddisfare le mie richeste
__________________
My gaming placement
franksisca è offline   Rispondi citando il messaggio o parte di esso
Old 02-04-2012, 16:47   #2
banryu79
Senior Member
 
L'Avatar di banryu79
 
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
Ciao franksisca, tre cose: primo puoi "snellire" e rifattorizzare un po' il codice per rendere il tutto più leggibile, ad esempio in questo modo (ma ovviamente va a gusti personali):
Codice:
public class CompareDateFields {
    
    enum Mese {
        GEN("gennaio"), FEB("febbraio"), MAR("marzo"), APR("aprile"), 
        MAG("maggio"), GIU("giugno"), LUG("luglio"), AGO("agosto"), 
        SET("settembre"), OTT("ottobre"), NOV("novembre"), DIC("dicembre");
        
        final String name;
        
        Mese(String n) {
            name = n;
        }
    }
    
    static class SimilData implements Comparable<SimilData> {
        final int day;
        final int mounth;
        final int year;
        
        SimilData(String giorno, String mese, String anno) {
            this.day = Integer.parseInt(giorno);
            this.mounth = asInteger(mese);
            this.year = Integer.parseInt(anno);
        }

        private int asInteger(String mese) {
            for (Mese m : Mese.values()) 
                if (mese.equalsIgnoreCase(m.name)) 
                    return m.ordinal() + 1;
            throw new IllegalArgumentException(mese + " is not a valid mounth name.");
        }

        @Override public int compareTo(SimilData other) {
            int diff = year - other.year;
            if (diff != 0) return diff;
            diff = mounth - other.mounth;
            if (diff != 0) return diff;
            return day - other.day;
        }
        
        boolean before(SimilData other) {
            return this.compareTo(other) < 0;
        }
    }
    
//
// Example:
//
    
    public static void main(String[] args) {
        verificaData("15", "gennaio", "2014", "16", "gennaio", "2001");
        verificaData("15", "gennaio", "2014", "15", "gennaio", "2014");
        verificaData("15", "gennaio", "2014", "16", "gennaio", "2014");
        verificaData("15", "gennaio", "2014", "16", "aprile", "2014");
        verificaData("31", "dicembre", "2013", "15", "gennaio", "2014");
    }
    
    static void verificaData(String giorno1, String mese1, String anno1, 
                              String giorno2, String mese2, String anno2) {
        SimilData d1 = new SimilData(giorno1, mese1, anno1);
        SimilData d2 = new SimilData(giorno2, mese2, anno2);
        if (d1.before(d2)) System.out.println("d1 is before d2");
        else System.out.println("d1 is same day of or after d2");
    } 
}
Secondo, se avrai a che fare pesantemente con le date anche in futuro, puoi semplificarti di molto la vita usando questa libreria: http://joda-time.sourceforge.net/ che è molto comoda e ben pensata, secondo me.

Terzo: lo StackOverflowError viene lanciato dalla jvm quando appunto lo spazio sullo stack termina a causa di una chiamata ricorsiva troppo profonda nella applicazione. Sarò distratto ma nel tuo codice non ne vedo (di esplicite chiamate ricorsive) però vedo una cosa che mi puzza:
Codice:
/**
     *
     * da inserire nei changeItemState dei vari comboBox
     */
    private void verificaData() {
        String giorno1 = (String) this.giorniInizio.getSelectedItem();
        String mese1 = (String) this.meseInizio.getSelectedItem();
        String anno1 = (String) this.annoInizio.getSelectedItem();
        String giorno2 = (String) this.giorniScadenza.getSelectedItem();
        String mese2 = (String) this.mesiScadenza.getSelectedItem();
        String anno2 = (String) this.annoScadenza.getSelectedItem();
        if (!(compare2Dates(giorno1, convertiMese(mese1), anno1, giorno2, convertiMese(mese2), anno2))) {
            this.giorniScadenza.setSelectedItem(this.giorniInizio.getSelectedItem());
            this.mesiScadenza.setSelectedItem(this.meseInizio.getSelectedItem());
            this.annoScadenza.setSelectedItem(this.annoInizio.getSelectedItem());
        }
    }
In questo metodo, se non sbaglio, ogni volta che chiami un setSelectedItem (e che la condizione testata in compare2Dates è vera) si scatena l'evento changedItemState del combo box corrispondente (viene pubblicato l'evento nella event queue che verrà processato appena possibile dall'edt) che a sua volta causa una nuova chiamata (futura) al metodo stesso.
Non ci metterei la mano sul fuoco, ma questa potrebbe essere la causa dell'esaurimento dello stack.
Nel caso lo fosse, dovresti, verificata la condizione e prima di chiamare i setSelectedItem, "staccare" e mettere da parte tutti i listener dell'evento change item state dei combo box, chiamare i setSelectedItem, e infine ripristinare i listener staccati.
__________________

As long as you are basically literate in programming, you should be able to express any logical relationship you understand.
If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it.
(Chris Crawford)

Ultima modifica di banryu79 : 02-04-2012 alle 16:50.
banryu79 è offline   Rispondi citando il messaggio o parte di esso
Old 02-04-2012, 16:48   #3
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Ti va in loop da qualche parte. Probabilmente nel changelistener fai qualcosa che comporta il rilascio di un ulteriore ChangeEvent. Nel codice del ChangeListener prima di fare qualsiasi altra cosa verifica che il valore attuale della casella combinata sia effettivamente cambiato (puoi ad esempio conservare l'indice dell'ultimo elemento selezionato e compararlo con quello dell'elemento attualmente selezionato per verificare se sia cambiato qualcosa oppure sia un "misfire").
__________________
Uilliam Scecspir ti fa un baffo? Gioffri Cioser era uno straccione? E allora blogga anche tu, in inglese come me!
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 03-04-2012, 08:04   #4
franksisca
Senior Member
 
L'Avatar di franksisca
 
Iscritto dal: May 2005
Città: Roma
Messaggi: 7938
grazie ad entrambi:

@banryu79
il refactoring da te consigliato mi piace molto, sinceramente nella prima bozza di codice butto tutto lì e poi refattorizzo dopo, a "programma completo" (lo sò che è bruttina come cosa, oltre che dispendiosa, ma quando non ho il tempo di pianificare la programmazione non riesco a fare di meglio)

Per l'utilizzo di librerie....purtroppo mi trovo costretto da direttive superiori (ovviamente non competenti nel campo) ad utilizzare le combobox in questo modo, che io odio. in passato ho usato JCalendar e mi sono trovato verametne molto bene...ma ripeto che non dipende da me

probabilmente il problema dello stack è proprio lì, devo rivedere quella parte di codice come da te consigliato.

@pgi-bis
probabilmente và in loop nella parte di codice selezionata da banryu79, ovvero si richiamano in cascata i "cambiamenti delle combobox". ora inserisco un check come da te suggerito sul precedente indice selezionato e dovrei risolvere.
__________________
My gaming placement
franksisca è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


realme 16 Pro Harry Potter Edition: il nuovo midrange ha uno stemma di Hogwarts che cambia colore al sole! realme 16 Pro Harry Potter Edition: il nuovo mid...
Recensione REDMI Note 17 Pro: il midrange con batteria da 8.340 mAh e ricarica veloce Recensione REDMI Note 17 Pro: il midrange con ba...
Insta360 Luna Ultra: la potenza del sensore da 1 pollice incontra la portabilità estrema Insta360 Luna Ultra: la potenza del sensore da 1...
Marvel's Wolverine, la recensione: Logan torna protagonista in un'avventura brutale e intensa Marvel's Wolverine, la recensione: Logan torna p...
DJI Romo 2: tante novità lo rendono un robot completo DJI Romo 2: tante novità lo rendono un ro...
iPhone 18 Pro, alcuni utenti segnalano p...
ChatGPT ti segue anche fuori dalla chat:...
Destiny 2 non è finito: Bungie ri...
iPhone 20 Pro, un nuovo leak anticipa i ...
Ricaricare l'auto con la stessa velocit&...
Generazione Z e lavoro: l'IA ripensa gli...
Samsung Galaxy Tab S12+ e S12 Ultra: spe...
Xiaomi lancia il nuovo Mijia 271L, il fr...
Risoluzione 2K nativa e sfondi trasparen...
iPhone 18 Pro, promosso da DXOMARK ma no...
vivo presenta la nuova serie X500: Pro M...
Tutte le offerte Amazon aggiornate, sono...
Trump annuncia l'AI Force e uno zar dell...
Marvel's Wolverine non include asset gen...
Nuova offerta WINDTRE, 200 GB in 5G a 5,...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 11:30.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v