Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 22
  1. #1
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    27

    [JAVA] Software multilingua

    Buon pomeriggio a tutti , sto facendo un programma, si tratta di un calcolatore, devo verificare che i dati inseriti siano corretti e poi grazie a un bottone fare, attraverso la formula, il calcolo, il programma è quindi molto semplice e le stringhe di feedback degli inserimenti poche. Sto utilizzando Eclipse e windowBuilder che semplifica il tutto. Il problema nasce nel momento in cui devo, grazie a un menù a tendina cambiare lingua alle stringhe. Per cambiare lingua a una JLabel ho quindi utilizzato una variabile per stringa. Il problema è che la stringa mi impone essere final, quindi non modificabile. Ho provato a creare una classe esterna che grazie a dei setter e dei getter impostasse la lingua. Ovviamente devono essere statici, ma mi sono bloccato perchè ho scoperto che non si può usare this in un metodo statico, lo so sto facendo un errore da principiante, ma ho iniziato a studiare questo bellissimo linguaggio solo da pochi mesi
    Esiste un'alternativa (funzionante) a ciò che ho fatto?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Esiste un'alternativa (funzionante) a ciò che ho fatto?
    Dovresti sfruttare le funzionalità di internazionalizzazione/localizzazione offerte dal framework. Direi innanzitutto che è meglio se leggi: Trail: Internationalization
    E poi se hai dubbi specifici, chiedi pure.
    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
    Registrato dal
    Jul 2013
    Messaggi
    27
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Dovresti sfruttare le funzionalità di internazionalizzazione/localizzazione offerte dal framework. Direi innanzitutto che è meglio se leggi: Trail: Internationalization
    E poi se hai dubbi specifici, chiedi pure.
    Ottimo consiglio, oggi mi sono guardato diverse delle funzioni che mi ha dato tu, molto utili direi, ma questo sarebbe stato un eventuale problema che sarebbe sorto poi, ma intanto è risolto, non riesco comunque a schiodarmi dal mio problema, forse non mi sono spiegato bene ci riprovo.

    Ho creato il mio programma con windowBuilder, attraverso dei listener verifico che il dato inserito sia accettabile (deve essere un numero intero o float a seconda dei casi). Grazie a questi listener modifico il testo della label del feedback della textfield. Il testo del messaggio l'ho messo come String prima del listener, facendo riferimento a una variabile esterna al listener, la stringa deve essere final, quindi non modificabile. Quindi non posso nemmeno modificare la lingua del programma. Spero di essermi spiegato, le spiegazioni non sono il mio forte lo so

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Il testo del messaggio l'ho messo come String prima del listener, facendo riferimento a una variabile esterna al listener, la stringa deve essere final, quindi non modificabile. Quindi non posso nemmeno modificare la lingua del programma.
    Ecco .... cerca di non "fissarti" sul fatto che hai voluto far usare una variabile locale di un metodo da parte di un listener che hai sicuramente implementato con una anonymous inner-class in quel metodo. Le regole appunto richiedono che la variabile locale sia final affinché sia visibile e usabile nella classe anonima.

    Se a seguito di un evento (es. per dire, click su una voce di menù "langue française") vuoi cambiare dei testi in francese, bene, prenderai un ResourceBundle con un Locale per il francese, prenderai le N stringhe e le assegnerai dove vuoi. Ma questo non è che per forza implica l'uso di variabili locali accedute da una classe anonima! Anzi ...

    Inoltre tieni anche presente una questione importante in questi scenari: il "quando" applicare il cambiamento della lingua. Le interfacce utente possono essere anche molto complesse, magari con più finestre aperte e/o con componenti messi in più sotto-contenitori e magari disposti con un layout che era stato dimensionato "giusto" per i testi nella lingua prima dello switch. Quindi tipicamente cambiare lingua "al volo" porta più problemi e grattacapi. Generalmente la soluzione più semplice è dire all'utente "la nuova lingua verrà applicata al prossimo avvio della applicazione". Se ti sembra strano/scomodo, sappi che molte applicazioni Java e non Java multilingua funzionano proprio così.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    27
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ecco .... cerca di non "fissarti" sul fatto che hai voluto far usare una variabile locale di un metodo da parte di un listener che hai sicuramente implementato con una anonymous inner-class in quel metodo. Le regole appunto richiedono che la variabile locale sia final affinché sia visibile e usabile nella classe anonima.
    Ecco so che ho sbagliato qua, ma potresti spiegarmi un po' meglio, ho creato un programma semplicissimo apposta perchè voglio capire dove sbaglio, correggimi tu, il programma non funziona, perchè se devo mettere la label final e modificarla non si può!

    codice:
    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.util.Locale;
    import java.util.ResourceBundle;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    
    
    
    public class esempio extends JFrame {
    
    
        private JPanel contentPane;
    
    
        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        esempio frame = new esempio();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
    
        /**
         * Create the frame.
         */
        public esempio() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(100, 100, 450, 101);
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(null);
            
            JButton btnItaliano = new JButton("Italiano");
            btnItaliano.setBounds(12, 12, 117, 25);
            contentPane.add(btnItaliano);
            
            JButton btnInglese = new JButton("English");
            btnInglese.setBounds(12, 43, 117, 25);
            contentPane.add(btnInglese);
            
            
            final JLabel label = new JLabel("Questo è un esempio per HTML.it");
            label.setBounds(164, 29, 250, 15);
            contentPane.add(label);
            
            //listener
            
            btnItaliano.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    Locale italy = Locale.ITALIAN;
                    ResourceBundle bundle = ResourceBundle.getBundle("trad", italy);
                    label.setText(""+bundle.getString(stringa));
                }
            });
            
            btnInglese.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    Locale usa = Locale.ENGLISH;
                    ResourceBundle bundle = ResourceBundle.getBundle("trad", usa);
                    label.setText(""+bundle.getString(stringa));
                }
            });
        }
    }
    e poi ovviamente in src ho creato i due file trad_it_IT.properties con scritto stringa = Questo è un esempio per HTML.it e trad_en_US.properties con scritto stringa = This is an example for HTML.it

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Ecco so che ho sbagliato qua, ma potresti spiegarmi un po' meglio, ho creato un programma semplicissimo apposta perchè voglio capire dove sbaglio, correggimi tu, il programma non funziona, perchè se devo mettere la label final e modificarla non si può!

    e poi ovviamente in src ho creato i due file trad_it_IT.properties con scritto stringa = Questo è un esempio per HTML.it e trad_en_US.properties con scritto stringa = This is an example for HTML.it
    Ok ... prima avevo capito un'altra cosa ma ora vedendo il codice è tutto chiaro.
    Il problema non è il final! La variabile 'label' tecnicamente deve essere final affinché sia usabile nelle due anonymous inner-class. Ma il fatto che è final significa solo che non puoi assegnare un altro oggetto JLabel alla variabile 'label' .... non che è proibito invocarci metodi es. setText.

    Il vero problema sono i Locale! Locale.ITALIAN è solo "it" ... non "it_IT" e Locale.ENGLISH è solo "en" ... non "en_US".
    Insomma, "it" (italiano) è più generico sia di "it_IT" (italiano in Italia) sia es. di "it_CH" (italiano in Svizzera).
    Quindi "it" non va a prendere trad_it_IT.properties .... potrebbe invece trovare trad_it.properties

    Idem per l'inglese.

    E inoltre il codice così come l'hai postato non compila, perché stringa viene cercato come variabile che non esiste.

    label.setText(""+bundle.getString(stringa)); // NO, Cerca una variabile di nome stringa che non esiste nel tuo codice

    label.setText(""+bundle.getString("stringa")); // OK


    Nota che il ""+ non serve ... getString dà già un String.


    EDIT: aggiungo una cosa, giusto per chiarezza. Se hai solamente:
    trad_it_IT.properties
    trad_en_US.properties

    se usi Locale.ITALIAN o Locale.ENGLISH nessuno di questi due Locale va a prendere i tuoi properties. Ma il ResourceBundle potrebbe comunque prendere trad_it_IT.properties ... perché?
    Perché se hai il PC come è configurato il mio, ovvero lingua italiana per l'Italia, il Locale di "default" della piattaforma è "it_IT". Se ResourceBundle non trova nulla con il Locale specificato a getBundle, usa un meccanismo di "fallback" e cerca con il Locale di default. E "it_IT" può trovare appunto trad_it_IT.properties.


    NOTA: Già che ci sono, ti segnalo alcune cose in generale:

    1) Abituati a tenere i riferimenti ai componenti come variabili di istanza della tua classe. Es.:

    codice:
    public class esempio extends JFrame {
        private JPanel contentPane;
        private JLabel label;   // <------
        .....

    Ti facilita di molto le cose, specialmente se i componenti devono essere usati anche da altri metodi della classe. Se non li vuoi tenere tutti, tieni almeno quelli con cui sai che devi interagire in seguito alla creazione della interfaccia.

    2) Un MouseListener ovviamente è tecnicamente corretto sui pulsanti JButton ma se ti serve solo sentire la "azione" del pulsante c'è un listener più appropriato: ActionListener che ha public void actionPerformed(ActionEvent e)
    Abituati ad usarlo sui pulsanti/menù.
    Ultima modifica di andbin; 25-04-2014 a 12:06
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    27
    Ho capito tutto tranne questo:

    Quote Originariamente inviata da andbin Visualizza il messaggio
    1) Abituati a tenere i riferimenti ai componenti come variabili di istanza della tua classe. Es.:

    codice:
    public class esempio extends JFrame {
        private JPanel contentPane;
        private JLabel label;   // <------
        .....

    Ti facilita di molto le cose, specialmente se i componenti devono essere usati anche da altri metodi della classe. Se non li vuoi tenere tutti, tieni almeno quelli con cui sai che devi interagire in seguito alla creazione della interfaccia.
    Un' altra cosa, adesso non mi dà errori, ma comunque non mi traduce in inglese quando clicco sul bottone english, perchè?
    Ti posto il codice così ci capisci megli anche tu:

    codice:
    import java.awt.EventQueue;
    import java.util.Locale;
    import java.util.ResourceBundle;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.EmptyBorder;
    import javax.swing.JButton;
    import javax.swing.JLabel;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    
    
    
    public class esempio extends JFrame {
    
    
    	private JPanel contentPane;
    
    
    	/**
    	 * Launch the application.
    	 */
    	public static void main(String[] args) {
    		EventQueue.invokeLater(new Runnable() {
    			public void run() {
    				try {
    					esempio frame = new esempio();
    					frame.setVisible(true);
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		});
    	}
    
    
    	/**
    	 * Create the frame.
    	 */
    	public esempio() {
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setBounds(100, 100, 450, 101);
    		contentPane = new JPanel();
    		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    		setContentPane(contentPane);
    		contentPane.setLayout(null);
    		
    		JButton btnItaliano = new JButton("Italiano");
    		btnItaliano.setBounds(12, 12, 117, 25);
    		contentPane.add(btnItaliano);
    		
    		JButton btnInglese = new JButton("English");
    		btnInglese.setBounds(12, 43, 117, 25);
    		contentPane.add(btnInglese);
    		
    		
    		final JLabel label = new JLabel("");
    		label.setBounds(164, 29, 250, 15);
    		contentPane.add(label);
    		
    		//listener
    		
    		btnItaliano.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent arg0) {
    				Locale italy = new Locale("it","IT");
    				ResourceBundle bundle = ResourceBundle.getBundle("trad", italy);
    				label.setText(bundle.getString("stringa"));
    			}
    		});
    		btnInglese.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent e) {
    				Locale usa = new Locale("en","US");
    				ResourceBundle bundle = ResourceBundle.getBundle("trad", usa);
    				label.setText(bundle.getString("stringa"));
    			}
    		});
    	}
    }

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Ho capito tutto tranne questo:
    1) Abituati a tenere i riferimenti ai componenti come variabili di istanza della tua classe.
    Questa è la parte più semplice ... è solo un aspetto logico/pratico.

    Se un ActionListener lo implementi ad esempio a livello della tua classe esempio e il JLabel label lo dichiari solo come locale al costruttore ... non lo puoi usare altrove.

    codice:
    public class esempio extends JFrame implements ActionListener {
        ....
        public esempio() {
            ....
            JLabel label = new JLabel("");
            ....
        }
    
        public void actionPerformed(ActionEvent e) {
            // qui ovviamente non potresti usare 'label'
        }
    }

    Quindi indipendentemente da quale è il design della tua classe e da come/dove implementi i listener, è sicuramente buona cosa se tieni i riferimenti ai componenti che poi usi molto come variabili di istanza piuttosto che come variabili locali.

    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Un' altra cosa, adesso non mi dà errori, ma comunque non mi traduce in inglese quando clicco sul bottone english, perchè?
    Il codice di per sé mi risulta corretto e adesso è anche corretto dal punto di vista dei Locale che vuoi cercare.

    Se hai i due file:
    trad_it_IT.properties
    trad_en_US.properties

    il tuo codice dovrebbe funzionare senz'altro. Se non funziona è probabile che non riesca a trovare i due properties. E se non trova nessuno dei due dovrebbe pure scatenare un bel java.util.MissingResourceException che dovresti vedere sulla console.

    I bundle di risorse vengono cercati usando un ClassLoader, ovvero sfruttando la ricerca lungo il "classpath". La directory che contiene i due file di properties deve essere in classpath. Se non sai ancora bene del classpath, l'argomento è assolutamente da approfondire.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it
    Registrato dal
    Jul 2013
    Messaggi
    27
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Quindi indipendentemente da quale è il design della tua classe e da come/dove implementi i listener, è sicuramente buona cosa se tieni i riferimenti ai componenti che poi usi molto come variabili di istanza piuttosto che come variabili locali.
    Certo ho capito perfettamente quello che vuoi dire adesso, ma io i listener li ho dichiarati internamente a public esempio() non esternamente, e la label riesco a usarla tranquillamente poichè è tutto interno ad esempio()

    Comunque avevo sbagliato una cavolata, mi ero dimenticato il .properties nella traduzione in inglese hahaha , il programma adesso funziona alla grande, fa quello che voglio che faccia, provo ad applicare queste modifiche sul programma originale di partenza, non dovrei riscontrare problemi, almeno lo spero, grazie mille sei stato molto utile

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da wasd28 Visualizza il messaggio
    Certo ho capito perfettamente quello che vuoi dire adesso, ma io i listener li ho dichiarati internamente a public esempio() non esternamente, e la label riesco a usarla tranquillamente poichè è tutto interno ad esempio()
    Certo, certo, nel tuo caso è ok. Lo dicevo giusto in generale per te, in futuro. Immagina di avere un programma ben più complesso, con 20/30 componenti .... non è particolarmente bello e "leggibile" fare tutto nel costruttore sparpagliando lì dentro variabili final e anonymous inner class!
    Prendilo appunto come suggerimento per altri sviluppi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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 © 2025 vBulletin Solutions, Inc. All rights reserved.