2010-07-23 15 views
6

Sono sicuro che ci sono molti metodi, ma qual è il modo migliore per farlo con meno impatto sul codice?Quali sono le migliori pratiche per l'internazionalizzazione di un'applicazione desktop Java Swing?

L'ovvio è che si creano file di proprietà, ma come si scambiano i valori nel rendering? In J2EE riproduci sempre l'intera pagina in modo semplice. Ma nelle app Swing, basta aggiungere il codice per .getProperty() nel metodo paintComponent (Graphics g)?

Se questo è il caso, non le sembra pesante visto che ora si dovrà eseguire l'override di questo metodo in tutto il mondo dove prima non hai bisogno di ...

aggiuntive: come si fa configurare un sistema di notifica per ri-renderizzare tutti i componenti attualmente visibili senza forzare alcun tipo di schema di registrazione?

Credo che se mi sovrascrivere paintComponent (Graphics g) tutto quello che devo fare è generare un evento che qualcosa è cambiato e il metodo paintComponent (Graphics g) sarà chiamato ...

+1

Il modo più semplice: chiedere all'utente di riavviare il programma, affinché le modifiche abbiano effetto. – Untitled

risposta

1

L'unica soluzione mi è venuta era quello di creare un enorme registro di tutti i componenti che avrebbe bisogno di essere ri-renderizzati. Quindi, se viene effettuata una chiamata per cambiare Locale, puoi semplicemente chiamare il registro e passerà attraverso tutti i componenti registrati e regolerà i loro valori. Così, per esempio, per tutti i JLabels registrati farà qualcosa sulla falsariga di

for(JLabel specificJLabel : REGISTRY.registeredJLabels) 
{ 
    String localeKey = specificJLabel.getActionCommand(); 
    specificJLabel.setText(ResourceBundle.getString(localeKey)); 
} 

dove la chiave Locale è memorizzato nel componenti ActionCommand. Quindi, qualunque schermo sia attualmente sottoposto a rendering, il pannello principale principale è responsabile per il nuovo rendering. Anche in questo modo il registro non deve gestire le chiavi Locale, queste sono completamente disaccoppiate dal registro. Ogni componente è responsabile della gestione delle proprie chiavi locali nel ResourceBundle.

0

Quello che vi serve è un ResourceBundle che consente di avere un file di proprietà basato su Locale a cui si accede come un file di proprietà.

Here is a sample on how to do it

+1

Capisco che, non è davvero la domanda. La domanda è dove si chiama il ResourceBundle nei componenti in modo che sia reso (o ri-reso) quando necessario. C'è un altro modo che sovrascrivere paintComponent (Graphics g) su ogni JComponent? –

+0

@Stephane Grenier - Di solito un utente avvia un programma in un paese diverso e ha bisogno di una lingua diversa in base alla lingua in cui si trova. Poiché nell'esempio si aggiungono le cose I18 in fase di costruzione sarà difficile. Dovresti cambiare la locale e almeno chiudere la finestra e ricrearla, o in base alla chiamata del widget setText() o qualsiasi altra cosa. –

+0

Purtroppo devo essere in grado di farlo dal vivo, è per un'applicazione kiosk su cui sto lavorando. Penso di poterlo fare ignorando i metodi paintComponent e con un pensiero attento. Speravo solo che ci fosse un metodo più semplice. –

1

Sostenere i cambiamenti dinamici lingua è un problema difficile. La soluzione più semplice è organizzare l'interfaccia utente in modo da poter ricreare eventuali pannelli visibili. Ciò evita la necessità di registrare o aggiornare componenti, quando la lingua cambia, è sufficiente ricreare la vista.

Ovviamente si perde lo stato di tutti i componenti visibili che possono essere un problema, ma di solito è lo stesso in un'app Web quando la pagina viene aggiornata.

3

Per quanto ne so, alcune applicazioni utilizzano i costruttori di layout/componente (consigliato da Karsten Lentzsch e parte dell'API JGoodies). Questi builder includono il codice per localizzare i componenti (usando ResourceBundle sotto il cofano).

Altre persone (me inclusa) preferiscono iniezione di risorse; questo è normalmente il metodo meno intrusivo. Questo è il modo scelto dallo Swing Application Framework (JSR-296) e da altri framework GUI come Guts-GUI.

Si potrebbe anche voler dare un'occhiata a this question che è abbastanza simile al tuo.

Per quanto riguarda i cambiamenti del linguaggio "al volo" (Locale notifica di modifica), penso che sia più facile da implementare quando si utilizza l'iniezione di risorse (ho implementato questo Guts-GUI già, altalena Application Framework può anche avere, ma io non ne sono sicuro).

Java non offre alcun modo per ascoltare le modifiche Locale, quindi è necessario creare il proprio "Servizio locale" (a cui è necessario indirizzare qualsiasi richiesta di modifica delle impostazioni internazionali). In questo servizio, è necessario enumerare tutte le finestre visibili (questo è possibile con Window.getWindows(), non è necessario registrare i componenti visibili prima) e quindi iniettare nuovamente le risorse.

Se volete un esempio, dare un'occhiata al pacchetto resource in Guts-GUI source code:

  • ResourceInjector mostra l'iniezione di risorse e il metodo di cambiare Locale, che invia un evento di notifica (utilizza un Evento Busper questo , ma semplici ascoltatori sarebbe bene anche) di questo cambiamento
  • WindowController ascolti per Locale eventi di modifica

Il codice interessante per l'aggiornamento di tutte le finestre visibili viene copiato in futuro:

for (Window window: Window.getWindows()) 
{ 
    if (window.isVisible()) 
    { 
     injectResources(window); 
     window.repaint(); 
     if (window instanceof RootPaneContainer) 
     { 
      ((RootPaneContainer) window).getRootPane().revalidate(); 
     } 
    } 
} 
1

Java 6 SE consente di ricaricare bundle di risorse al volo. Basta chiamare la funzione statica clearCache() della classe ResourceBundle. Quindi chiamare di nuovo getBundle().

Vedi this article sotto Cache Controlli

Problemi correlati