# Internationalisierung



## Angel4585 (27. Aug 2007)

Hallo,

ich möchte eine Anwendung schreiben bei der ich mehrere Sprachen zur Verfügung stellen möchte.
Wie mache ich das am Besten?
Also es sollen die Texte von Labels usw. durch den Text der jeweiligen Sprache ersetzt werden.  ???:L 

Gibts da Methoden die angewandt werden, solche Standardabläufe oder so?


----------



## Wildcard (27. Aug 2007)

http://java.sun.com/developer/technicalArticles/Intl/ResourceBundles/


----------



## Marco13 (27. Aug 2007)

Ja, ResourceBundles braucht man da auch, aber nur nebenbei - der interessanteste Teil dürfte der hier sein:
http://java.sun.com/docs/books/tutorial/i18n/index.html


----------



## Leroy42 (27. Aug 2007)

Noch eine Wikipedia-Erklärung, wie der
Ausdruck I18N entstanden ist.
 :shock: 
Manchmal haben die Amis wirklich ein Rad ab!


----------



## byte (27. Aug 2007)

Naja, ist doch ein klassicher Informatiker-Gag.


----------



## Angel4585 (30. Aug 2007)

Ich habe mir das jetzt mal angeschaut un bin jetz an folgendem Punkt:

Ich arbeite mit Netbeans und habe dort in mein Package ein ResourceBundle erzeugt.
Dieses bundle enthält drei Sprachen - deutsch, englisch und franösisch.

Jetzt wird bei nem Label zB bei Text folgendes reingeschrieben:

```
jLabel1.setText(java.util.ResourceBundle.getBundle("testprojekt/lng").getString("TestLabel"));
```

wobei testprojekt das package und lng das bundle ist.

hier wird glaube ich die defaultlanguage geladen, oder?
Was muss ich jetzt genau tun um eine der beiden andern Sprachen zu laden? die sind ja im gleichen bundle?


----------



## Angel4585 (30. Aug 2007)

keiner ne Ahnung wie ich zur Laufzeit die Sprache änder?


----------



## Leroy42 (30. Aug 2007)

Angel4585 hat gesagt.:
			
		

> keiner ne Ahnung wie ich zur *Laufzeit* die Sprache änder?



Sicher! Dazu mußt du eine Methode schreiben, die *alle* Labels und Buttons
entsprechend ändert:


```
void setNewLanguage() {
  label1.setText(...);
  button1.setText(...);
  ...
}
```


----------



## Angel4585 (30. Aug 2007)

echt? gibts da nicht einfach bei dem ResourceBundle ne Methode die das macht?
nicht das ich irgendwo ein Label doer so vergiss...


----------



## Wildcard (30. Aug 2007)

Nein, es gibt dafür keine Möglichkeit.
Daher bietet es sich an den Sprachwechsel mit einem Neustart des Programms zu verknüpfen.


----------



## Leroy42 (30. Aug 2007)

Wildcard hat gesagt.:
			
		

> Daher bietet es sich an den Sprachwechsel mit einem Neustart des Programms zu verknüpfen.


 :shock:  :shock:  :shock: 
Wozu das denn?  ???:L 


Nicht wenn man von Anfang an den hierfür _korrekten_ Code schreibt!


----------



## Wildcard (30. Aug 2007)

Dann sag mir bitte das Allheilmittel wie du *jeden* String updaten kannst?
Die Sprache wechselt in der Regel sowieso kein Mensch, weil beim startup schon das richtige Locale gewählt wird.
Warum Unmengen an Zeit in ein sinnloses Feature investieren?


----------



## Leroy42 (30. Aug 2007)

Wildcard hat gesagt.:
			
		

> Dann sag mir bitte das Allheilmittel wie du *jeden* String updaten kannst?


Indem man von Anfang an alle Stringinitialisurungen in eine Methode
auslagert, die dann mit dem entsprechenden Resource-Bundle aufgerufen wird.



			
				Wildcard hat gesagt.:
			
		

> Die Sprache wechselt in der Regel sowieso kein Mensch, weil beim startup schon das richtige Locale gewählt wird.


Das ist noch lange kein Grund, den Sprachwechsel in einem
sauberen Programm anzubieten.



			
				Wildcard hat gesagt.:
			
		

> Warum Unmengen an Zeit in ein sinnloses Feature investieren?



Gute Frage!   
Deshalb schere ich mich ja auch selbst
eine Dreck darum, was ich anderen Leuten rate!


----------



## Wildcard (30. Aug 2007)

Leroy42 hat gesagt.:
			
		

> Indem man von Anfang an alle Stringinitialisurungen in eine Methode
> auslagert, die dann mit dem entsprechenden Resource-Bundle aufgerufen wird.


Das ja sowieso. Aber wie willst du auf die Art und Weise schon verwendete Strings nachträglich in der GUI ändern?


----------



## Angel4585 (30. Aug 2007)

ich müsste mir bei Netbeans dann also die Zeilen rauskopieren und in ne eigene Methode rein..
Das werd ich wohl so machen müssen 

Naja zwingend notwendig ist das nicht, mich interessiert es einfach und ich möchte mich weiterentwickeln und dazulernen.


----------



## Wildcard (30. Aug 2007)

In der Regel verwendet man eine Messages Klasse die statische Strings enthält. Je nach Mechanismus werden die Übersetzten Strings zum Programmstart in die Variablen geladen, oder du du verwendest Konstanten die als Key für das Bundle fungieren.
Aber wie gesagt, das erlaubt dir noch nicht die Sprache zur Laufzeit (ohne neustart) zu ändern.


----------



## Angel4585 (31. Aug 2007)

OK jetzt verstehe ich das mit den ResourceBundles. Hat ne weile gedauert:

Ein ResourceBundle enthält eine defaultLanguage und evtl mehrere "spezielle" Sprachen.
Ist die Systemsprache eine dieser speziellen Sprachen, wird automatisch auf diese zurückgegriffen, ansonsten auf die default Sprache.

Beispiel:

default ist Englisch, spezielle Sprachen sind deutsch und franz.

Wenn ich mit meinem deutschen BS drangeh wird mir automatisch das Programm im deutschen angezeigt.
Geht ein Inder dran, bekommt der englisch, weil indisch nicht dabei ist.

Aber wenn ich jetzt ne andere Sprache will als die die vom System vorgegeben ist? Das muss ich doch irgendwie festlegen können welche geladen werden soll. Gibts da nen Befehl oder so dafür? ???:L


----------



## FenchelT (31. Aug 2007)

Angel4585 hat gesagt.:
			
		

> keiner ne Ahnung wie ich zur Laufzeit die Sprache änder?




Ich realisiere die Geschichte immer ueber eine DB.
Dort trage ich alle Labels, Comboboxen, usw in unterschiedlichen Sprachen ein und lade die Daten vor dem anzeigen der Form. Funktioniert gut.

Und wenn der User ne andere Sprache wuenscht, wird das auch in den UserSettings in der DB gespeichert und so kann ich zur Laufzeit einfach die eingestellte Sprache abfragen und dann dann darstellen.


----------



## Wildcard (31. Aug 2007)

FenchelT hat gesagt.:
			
		

> Ich realisiere die Geschichte immer ueber eine DB.
> Dort trage ich alle Labels, Comboboxen, usw in unterschiedlichen Sprachen ein und lade die Daten vor dem anzeigen der Form. Funktioniert gut.


Und nochmal:
In einer normalen Anwendung kann man die Sprache damit nicht zur Laufzeit ändern (bzw. kann man schon, aber dadurch wird die GUI nicht aktualisiert).


----------



## FenchelT (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> FenchelT hat gesagt.:
> 
> 
> 
> ...





Hmm, vllt definieren wir "zur Laufzeit" unterschiedlich?  Vllt kannst Du mir ja mal erklaeren, was fuer Dich eine normale und was eine unnormale Anwendung ist?!
Wenn ich falsch liege, lasse ich mich selbstverstaendlich von Dir gerne eines besseren belehren, bin ja nur Laie und beschaeftige mich erst seit 3 Monaten mit der Sprache.

Jedenfalls liegst Du falsch, wenn DU meinst ich muesste um die Sprache zu aendern die Appl. neu starten.


Ich habe ein JFrame, auf dessen ContentPane ich ein JPanel anzeige.
Je nachdem welche Sprache (Integer Wert) ich dem Teil uebergebe, werden dementsprechend aus der DB alle Werte geholt und angezeigt.
Wenn ich das Panel wieder remove und neu hinzufuege mit einem anderen Integerwert ist die Sprache eine andere.


----------



## Wildcard (31. Aug 2007)

FenchelT hat gesagt.:
			
		

> Wenn ich das Panel wieder remove und neu hinzufuege mit einem anderen Integerwert ist die Sprache eine andere.


Exakt. Und als normale Anwendung definiere ich eine, die zu groß ist um das noch sinnvoll machen zu können.
Was glaubst wie viele tausend Label, Panels, Buttons, Trees,... in der Anwendung zu sehen sind, an der ich gerade entwickle?


----------



## FenchelT (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> FenchelT hat gesagt.:
> 
> 
> 
> ...



Ich tue mich im Moment schwer zu verstehen, wo das Problem liegt, vllt. erklaerst Du mir das ja mal.
Ich denke, ich muss nochnichtmal das Panel removen und behaupte, es geht auch per Knopfdruck.
Wie viele Controls hast Du maximal auf einem Panel? 50? Ich lade doch nur die Benamung der Controls aus der DB die ich fuer die aktuelle anzeige brauche. Das duerfte auch kaum zeitkritisch sein.

Ich werde meine Behauptung von oben "geht auch auf Knopfdruck" am WE mal testen und dann den Code posten.

Viele Gruesse und Dir noch ein schoenes WE


----------



## Wildcard (31. Aug 2007)

Wie willst du den rausfinden welche Controls überhaupt da sind? 
Meine Anwendung basiert beispielsweise auf einem PlugIn Konzept (Eclipse bzw. OSGi im konkreten Fall).
Ich habe zur Laufzeit keine Ahnung was der User gerade so vor sich sieht.
Bringst du jedem Tree einzeln  bei das er seine Labels updaten muss?
setText auf jedem Button?
Meldet sich bei dir etwa jeder Mist an irgendeiner Registry an, nur damit du die Sprache zur Laufzeit wechseln kannst?
Ich weigere mich nämlich diesen Aufwand für ein unnützes Feature zu betreiben.


----------



## Yzebär (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> Und nochmal:
> In einer normalen Anwendung kann man die Sprache damit nicht zur Laufzeit ändern (bzw. kann man schon, aber dadurch wird die GUI nicht aktualisiert).



"Kann man immer" oder "kann man nie" sind Aussagen, die ein Entwickler niemals treffen sollte!

Man kann eine Methode definieren, die alle in der GUI-Komponente vorhandenen Strings entsprechend der aktuell eingestellten Sprache befüllt und die GUI-Komponente aktualisiert. Diese Methode wird aufgerufen, wenn die GUI-Komponente erzeugt wird oder wenn die Sprache umgestellt wird (dabei wird ein Ereignis ausgelöst, auf das alle aktuell erzeugten GUI-Komponenten reagieren).


----------



## FenchelT (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> Ich weigere mich nämlich diesen Aufwand für ein unnützes Feature zu betreiben.



Das steht doch gar nicht zur Diskussion, wobei mir gerade Deine Signatur auffaellt  :wink: 
Die Frage war doch einfach ob es moeglich ist zur LAufzeit die Sprache zu wechseln?!

Und Deine Aussage war, dafuer muesse man die Appl. neu starten.
Meine war, das muss man nicht, ich kann das ganze aus der DB laden.

Ob Du das nun fuer Dich und Deine 1000 Controls in Anspruch nimmst oder nicht ist doch Dir ueberlassen.
Meine Appl. laufen, ohne dass ich dem User zumuten muss, fuer sowas die Appl. neu zu starten.

In einer Sache hast Du recht, da muss ich meine Aussage relativieren, weil ich im MOment nicht die Zeit habe, das Gegenteil zu testen und zu beweisen. Im Moment gehe ich davon zu wissen, welche Controls z.B. auf dem angezeigten Panel vorhanden sind.



So, nun aber wirklich ein schoenes WE, habe noch einen Termin


----------



## Wildcard (31. Aug 2007)

Yzebär hat gesagt.:
			
		

> Wildcard hat gesagt.:
> 
> 
> 
> ...


Zu beachten ist das 'damit' bezogen auf die bisher erwähnten Methodiken. Das es generell möglich ist, ist mir bewusst.
Nur bin ich gespannt, ob jemand der Beteiligten auch einen praktikablen Weg zeigen kann....



> Und Deine Aussage war, dafuer muesse man die Appl. neu starten.
> Meine war, das muss man nicht, ich kann das ganze aus der DB laden.


Ob DB oder Bundle ist Jacke wie Hose. Tatsache ist, die schon verwendeten Strings werden sich nicht durch Zauberei aktualisieren. Du verwendest also entweder ein komplexes Konstrukt um die Aktualisierungen vorzunehmen, oder dir ist ein einfacher Weg bekannt. Sollte letzteres der Fall sein, würde mich der Weg interessieren.


----------



## Wildcard (31. Aug 2007)

FenchelT hat gesagt.:
			
		

> In einer Sache hast Du recht, da muss ich meine Aussage relativieren, weil ich im MOment nicht die Zeit habe, das Gegenteil zu testen und zu beweisen. Im Moment gehe ich davon zu wissen, welche Controls z.B. auf dem angezeigten Panel vorhanden sind.


Wenn du nur ein Panel hast, ist die Sache ohnehin trivial.
Welche Anwendung besteht aber heutzutage aus einem einzigen Panel?
Da kommen JTabbedPanes, verschiedene Views, verschiedene Editoren, JInternalFrames, Outline,...
Das alles zur Laufzeit zu aktualisieren ist nicht witzig.


----------



## tuxedo (31. Aug 2007)

Die ganzen Swing-Komponenten sind doch irgendwie miteinander verknüpft. Jedes JLabel weiß doch, in welchem JPanel es ist, oder?

Das ganze bildet irgendwie eine Baumstruktur. Könnte man da nicht was basteln das die Elemente durchgeht und die Namen neu setzt, sowie ein repaint oder sowas auslöst?

Etwas "ähnliches" hab ich mal in einem Projekt gemacht. Da gings drum dass ich eine komplexe Eingabemaske mit vielen Labels, Textfeldern, Liste, Comboboxen und TabbedPanes etc. hatte. Anhand des Namens der Elemente (gesetzt mit setName()) und des Objekttyps, konnte ich dann in einer einzigen Methode, mit einer etwas größeren Schleife die ganze Eingabemaske befüllen. 

Hat prima geklappt. Und ob ich so jetzt Eingabefelder befülle, oder Buttonbeschriftungen und Labels eine andere Sprache verpasse, ist doch dann wurscht, oder?

Ich seh da eigentlich kein sooo großes Problem drin. Aber vielleicht waren meine Eingabemasken mit um die 5000 Zeilen Code (nur die GUI der Eingabemaske, keine Logik) noch zu klein um da auf größere Probleme zu stoßen. 

- Alex


----------



## Yzebär (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> Wenn du nur ein Panel hast, ist die Sache ohnehin trivial.
> Welche Anwendung besteht aber heutzutage aus einem einzigen Panel?
> Da kommen JTabbedPanes, verschiedene Views, verschiedene Editoren, JInternalFrames, Outline,...
> Das alles zur Laufzeit zu aktualisieren ist nicht witzig.



Aber alle diese Komponenten können sich beim Erzeugen als Klienten anmelden, die sich für das Event "Sprache hat sich geändert" interessieren und wenn das Event eintritt, aktualisieren sie sich. Man kann das auch beliebig strukturieren, so daß zB ein Panel alle Elemente aktualisiert, die es beherbergt... oder sich jedes einzelne Element selbst aktualisiert... usw... 

Man muß gar nicht wissen, welche GUI-Elemente vorhanden sind und diese dann irgendwie referenzieren, da alle GUI-Elemente (egal nach welchem Schema, ich würde allerdings favorisieren davon auszugehen, daß jeder Frame seine beinhalteten Elemente aktualisert) sich bei Ihrer Erzeugung beim "Sprache hat sich geändert"-Observer anmelden und beim schließen wieder abmelden. Der "Sprache hat sich geändert"-Observer weiß dann immer automatisch, welche GUI-Komponenten aktualisiert werden müssen und ruft deren Aktualisierungsmethode auf.

Da man die Sprache nicht oft wechselt, kann das dann auch mal ein paar Millisekunden länger dauern, schneller als die Applikation zu schließen und neu zu starten ist es aber auf jeden Fall.


----------



## Wildcard (31. Aug 2007)

Diese Möglichkeit ist mir bekannt, aber empfindest du das als praktikabel?
Jede GUI Klasse sollte dementsprechend über eine updateLanguage Methode verfügen, was bedeutet, das du keine GUI Klasse einfach verwenden kannst, sondern alle erweitern musst. Bei SWT kommt erschwerend hinzu, das sich sehr viele Controls gar nicht erweitert werden können, bzw. nicht erweitert werden sollen.
Alternativ muss die ganze Logik in die Controller Schicht verlagert werden, aber was hat die Controller Schicht mit der Anzeigesprache zu schaffen? Auch das empfinde ich nicht als schöne Lösung.
Und dieser ganze Aufwand für einen Fall der praktisch nie auftritt?
Jetzt mal Hand auf's Herz:
Wer von euch hat eine größere Anwendung schon auf diese Weise implementiert?


----------



## FenchelT (31. Aug 2007)

Wildcard hat gesagt.:
			
		

> Jetzt mal Hand auf's Herz:
> Wer von euch hat eine größere Anwendung schon auf diese Weise implementiert?



Hallo nochmal,

wenn Du unter groessere Anwendung so etwas verstehst wie das wovon Du die ganze sprichst lege ich meine Hand aufs Herz und sage ganz ehrlich, ich nicht  :wink: 

Vllt sollten wir den Threaderoeffner nicht noch mehr verschrecken (er/sie meldet sich ja gar nicht mehr  :roll: ) und koennen uns darauf verstaendigen zu sagen, es haengt einfach vom Anwendungsfall ab. :wink:

So long
FenchelT


----------



## Wildcard (31. Aug 2007)

Vorher würde mich noch deine Methode interessieren.
Yzebär hat die Möglichkeit genannt die mir auch eingefallen ist, jedoch wollte ich so etwas definitiv nicht in die Praxis umsetzen.
Also, wie setzt du die Werte deiner DB auf die schon erzeugten Widgets um wenn sich die Sprache ändert?


----------



## FenchelT (31. Aug 2007)

Hallo wildcard,

ich werde Dir hier am WE wie versprochen noch ein paar Zeilen Code posten.


Bis dahin noch einen schoenen Abend.


----------



## Wildcard (31. Aug 2007)

Ebenfalls  :wink:


----------



## Angel4585 (2. Sep 2007)

OK, ich ahb mich mit mir jetzt drauf geeinigt das ein Programmneustart akzeptabel ist 
Aber was dann? ich muss dann doch irgendwo festlegen welche Sprache geladen werden soll? Wann, wo und wie muss das passieren?


----------



## Wildcard (2. Sep 2007)

Angenommen du hast eine Klasse Messages über die du alle Strings bekommst.
Die Klasse könnte dann zB so aussehen:

```
public class Messages
{
    private static final String         BUNDLE_NAME     = "lang.messages"; 
    private static ResourceBundle       RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
    private static Locale               CURRENT_LOCALE  = null;
    
    
    public static void setCurrentLocale(Locale newLocale)
    {
        CURRENT_LOCALE = newLocale;
        RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, CURRENT_LOCALE);
    }
    
    public static String getString(String key)
    {
        if( RESOURCE_BUNDLE==null )
        {
            ResourceBundle.getBundle(BUNDLE_NAME);
        }
        
        try
        {
            return RESOURCE_BUNDLE.getString(key);
        }
        catch (MissingResourceException e)
        {
            return '!' + key + '!';
        }
    }
}
```
Über setCurrentLocale kannst du nun eine andere Sprache festlegen.


----------



## FenchelT (2. Sep 2007)

Hallo Wildcard,

wie versprochen hier ein paar Zeilen Code.
Ich habe der Einfachheit halber auf eine MVC Trennung verzichtet. Es geht ja auch eingentlich nur darum, das vorgehen aufzuzeigen.

Benoetigt eine Datenbank (bei mir heisst sie tests) und eine Tabelle (config).
Inhalt:

```
ID     typ      form   objname       objvalue     lang     sort                                      lflag
1	label	Test	lblName	        Name	    10	      NULL	                               A
2	label	Test	lblOrt	           Ort	          10	    NULL	                             A
3	label	Test	lblOrt	           City	          20	    NULL	                             A
4	label	Test	lblName	        Name	     20	       NULL	                                A
5	test	test	 lblTest	    test	   10	     NULL	                               L
6	label	Test	lblPlz	            Plz	           10	     NULL	                              A
7	label	Test	lblPlz	            ZipCode	20	NULL	                                  A
8	combo	Test	cboAnlage    Datei	   10	     2	                                        A
9	combo	Test	cboAnlage    Brief	   10	      1	                                        A
10	combo	Test	cboAnlage   Was auch immer	10	3	                        A
11	label	Test	lblAnlage        Anlage auswählen	10	NUL                       A
12	label	Test	lblAnlage        Select an Attachment	20	NULL                     A
13	combo	Test	cboAnlage   File	20	1	                                         A
14	combo	Test	cboAnlage   Letter	20	2	                                        A
15	combo	Test	cboAnlage   Whatever	20	3	                            A
```

Sorry erstmal dafuer, dass die Formtierung der Tabellendaten so fuerchterlich ist. Kann man hier im Forum eigentlich HTML-Tags benutzen?
Also es gibt eine ID, ein Controltyp, die Form auf der es angezigt wird, der Name des Controls, dessen Wert. die Sprache, eine Sortierung und ein Loeschflag (A= aktiv, L=Geloescht)



```
import java.sql.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Start 
{

	/**
	 * @param args
	 */
	
	static DBConnection db = null;
	
	public static void main(String[] args) 
	{
		try
		{
			db = new DBConnection("com.microsoft.sqlserver.jdbc.SQLServerDriver", 
		 			   "jdbc:sqlserver://localhost:1433;" +
					   "databaseName=tests","javaClient","habichauch");
			
			
			
			new DynamicGui(db);
		}
		catch(Exception ex)
		{
			System.out.println (ex);
		}

	}

}


class DynamicGui extends JFrame
{
	

		// Instanzvariablen
		private Connection cn = null;
		private ResultSet rs = null;
		private Statement stmt;
		private String strSQL = "";
		
		private JLabel lblName;
		private JLabel lblOrt;
		private JLabel lblPlz;
		private JLabel lblAnlage;
		private JLabel lblTabelle;
		private JLabel lblLeer;
		private JTextField txtName = new JTextField();
		private JTextField txtOrt = new JTextField();
		private JTextField txtPlz = new JTextField();
		private JComboBox cboAnlage;
		private JButton btnButton1;
		
		// Konstruktor
		public DynamicGui(DBConnection dbCon)
		{
			// Aufruf JFrame Konstruktor
			// --------------------------
				super("Test");
				
				
			// Hole bestehende dbConnection
			// ----------------------------
				this.cn = dbCon.getConnection();
			
				
			// Lege Layout fest
			// -----------------
				this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				this.getContentPane().setLayout(new GridLayout(10,2));
			
				
			// Platziere die Controls auf der ContentPane des JFrame
			// ---------------------------------------------------------
				this.setForm();
					
					
			// Lese Daten
			// --------------
				this.readData(20);			// lang = Language. 10 = Deutsch, 20 = Englisch
				
			
				
			// Button am Listener anmelden
			// -----------------------------
				this.btnButton1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event){readData(10);}});
			
				
			// Fertige Form anzeigen
			// ---------------
				showForm();
					
				
		} // end Konstruktor
		
		
		
	// Regelt die weitere Ablaufsteuerung des Programms
	// ---------------------------------------------------
		public void readData(int sprache)
		{
				
			// SQL zusammenbauen
			// ---------------------
				this.strSQL = "SELECT objname," +
							  "       objvalue, " +
							  "       typ " +
							  "FROM   config " +
							  "WHERE  form    = 'Test' " +		// form = Name der Form auf der sich die Objekte befinden
							  "AND    lang    = " + sprache +	// lang = Language. 10 = Deutsch, 20 = Englisch
							  "AND    lflag   = 'A' " +			// lflag = Loeschflag. A= Aktiv; L= Geloescht
							  "ORDER BY typ, sort";
				
			
			// Daten fuer  aus Datenbank holen
			// und anschliessend verarbeiten
			// ------------------------------------------
				this.rs = getGuiDataFromDB(cn, this.strSQL);
				initForm();

				
			
		}
		
		
	// Setzt die Controls auf die Form ohne sie zu befuellen oder zu benennen
	// ------------------------------------------------------------------------
		private void setForm()
		{
			lblLeer = new JLabel();
			lblLeer.setName("lblLeer");
			
			lblName = new JLabel();
			lblName.setName("lblName");			// Wichtig um später den Label vergleichen zu können
			
			lblOrt  = new JLabel();
			lblOrt.setName("lblOrt");
			
			lblPlz = new JLabel();
			lblPlz.setName("lblPlz");
			
			lblAnlage = new JLabel();
			lblAnlage.setName("lblAnlage");
			
			lblTabelle = new JLabel();
			lblTabelle.setName("lblTabelle");
			
			cboAnlage = new JComboBox();
			cboAnlage.setName("cboAnlage");
			
			btnButton1 = new JButton();
			btnButton1.setName("btnButton1");
			
			
			this.getContentPane().add(lblName);
			this.getContentPane().add(txtName);
			this.getContentPane().add(lblPlz);
			this.getContentPane().add(txtPlz);
			this.getContentPane().add(lblOrt);
			this.getContentPane().add(txtOrt);
			this.getContentPane().add(lblAnlage);
			this.getContentPane().add(cboAnlage);	
			this.getContentPane().add(lblLeer);
			this.getContentPane().add(btnButton1);
		}
		
		
	// Holt die Daten aus der DB und gibt ein REsultset zurück
	// ----------------------------------------------------------
		private ResultSet getGuiDataFromDB(Connection con, String s)
		{
			ResultSet rst = null;
			String sql = s;			
			
			try
			{
				this.stmt = con.createStatement();//ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_INSENSITIVE);
				rst = this.stmt.executeQuery(sql);
			}
			catch(Exception ex)
			{
				System.out.println("Folgender Fehler ist aufgetreten: " + ex);
			}
			
			return rst;
		}
		
		
	// Erzeugt die Benamung der Label
	// ---------------------------------
		private void initForm()
		{
			
			try
			{
				Component[] comps = this.getContentPane().getComponents();
				while(this.rs.next())
				{ 
					
					for (int i = 0; i < comps.length; i++) 
					{
						//Ab hier Label Prüfung
						if (this.rs.getString("typ").equals("label"))
						{
							if(comps[i] instanceof JLabel)
							{
								JLabel label = (JLabel) comps[i];
								if(label.getName().equalsIgnoreCase(this.rs.getString("objname")))
								{
									label.setText(this.rs.getString("objvalue"));
									break;
								} // end if
							} // end if
						} // end if
						
						
						//Ab hier Combo Prüfung
						if (this.rs.getString("typ").equals("combo"))
						{
							if(comps[i] instanceof JComboBox)
							{
								JComboBox combo = (JComboBox) comps[i];
							
								if(combo.getName().equalsIgnoreCase(this.rs.getString("objname")))
								{
									cboAnlage.addItem(this.rs.getString("objvalue"));
									break;
								} // end if
							} // end if
						} // end if
						
						
						//Ab hier Button Prüfung
						if (this.rs.getString("typ").equals("button"))
						{
							if(comps[i] instanceof JButton)
							{
								JButton button = (JButton) comps[i];
							
								if(button.getName().equalsIgnoreCase(this.rs.getString("objname")))
								{
									button.setText(this.rs.getString("objvalue"));
									break;
								} // end if
							} // end if
						} // end if
						
					} // end for
						
				} // end while
				
			} // end try
			catch(Exception e)
			{
				System.out.print("e");
			} // end catch
			
		}
		
	// Zeigt die Form auf dem Bildschirm an
	// ----------------------------------------
		private void showForm()
		{
			this.setSize(300, 400);
			this.setLocation(100, 100);
			this.setVisible(true);
		}
		
}
```

Ich wuerde dies allerdings so nicht umsetzen, da es aus meiner Sicht keinen Sinn macht innerhalb einer angezeigten GUI die Sprache zu wechseln.
Ich mache sowas ueber ein Administrationsmenu
Ich habe mir noch die Muehe gemacht zu zaehlen, auf wie viele Steuerelemente ich zur Zeit bei meinem Panel mit den meisten Controls komme; es sind 35.
Ich merke beim Laden keine Performanceprobleme.


----------



## Wildcard (2. Sep 2007)

Der Anatz ist sicherlich interessant, birgt aber Probleme.
1. Diese Art Code für jede Swing Klasse schreiben? (was ist mit eigenen Klassen?)
2. Ich denke es ist recht schwer zu bemerken wenn ein Name im Projekt mehrfach verwendet wird.
3. Was ist mit Datenbasierten Widgets? Trees, Tables,...
4. Was ist mit den nicht unmittelbar sichtbaren Dingen? Tooltips? Popup Menüs? Keystrokes? Alles einzeln auf diese Weise ändern?
5. Wie lwird bei einer Anzahl von n>1 Entwicklern sichergestellt, das für jede neue UI-Klasse dieser Monstercode nachgezogen wird?



			
				FenchelT hat gesagt.:
			
		

> Ich wuerde dies allerdings so nicht umsetzen, da es aus meiner Sicht keinen Sinn macht innerhalb einer angezeigten GUI die Sprache zu wechseln.
> Ich mache sowas ueber ein Administrationsmenu.



Ich bekomme immer mehr den Eindruck das wir hier auch von verschiedenen Dingen reden, da du sehr stark auf Formular basierte GUIs fixiert zu sein scheinst, während ich reichere UI-Designs gewöhnt bin und daher wohl auch eine andere Sicht auf die Thematik habe.


----------



## FenchelT (2. Sep 2007)

Wildcard hat gesagt.:
			
		

> Der Anatz ist sicherlich interessant, birgt aber Probleme.
> 1. Diese Art Code für jede Swing Klasse schreiben? (was ist mit eigenen Klassen?)
> 2. Ich denke es ist recht schwer zu bemerken wenn ein Name im Projekt mehrfach verwendet wird.
> 3. Was ist mit Datenbasierten Widgets? Trees, Tables,...
> ...



Hallo wildcard,

zu 1: 
Natuerlich schreibe ich diesen Code nicht fuer jede Swing GUI neu ;-)
Das war doch nur ein extra fuer Dich schnell zusammengetiipter Code, der auch testbar ist  :wink: 
Ich nutze eine statische Methode die als Parameter ein ResultSet oder ein CachedRowSet sowie ein JFrame uebergeben bekommt.
Diese Methode kann ich dann von ueberall aus aufrufen.


zu2:
Ein Name eines Controls kann ja in einem Projekt mehrfach vorkommen, allerdings sollte der Name einer Form eindeutig sein


zu3:
Ich bin ehrlich, habe ich noch nicht getestet, koennte aber durchaus etwas kniffliger werden  :wink: 

zu4:
Danke fuer den Hinweis, auch darueber muss ich mir nochmals Gedanken machen.

zu5:
Wie gesagt, es gibt nur eine statische Methode.  Aber auch hier bin ich gerne ehrlich; ich entwickle in der Regel alleine 


Dass wir von unterschiedlichen Dingen reden, glaube ich fast auch.
Vllt koennen wir das ja bei einem Bierchen klaeren, wenn ich das naechste Mal wieder beruflich in Karlsruhe bin ?!   :wink:


----------



## Wildcard (2. Sep 2007)

Für ein Bierchen bin ich immer zu haben...


----------



## Angel4585 (3. Sep 2007)

hmm.. eigentlich muss ich doch garnicht neustarten.
Da die Locales in der initComponent Methode geladen werden, reicht es doch wenn ich das Frame freigebe und neu erzeuge oder?

Allerdings bleibt dann immernoch die Frage wie ich diese Messages-Klasse in das Ganze einbinde.


----------



## Angel4585 (3. Sep 2007)

cool wenn ich Locale.setDefault(Locale.GERMAN); bzw Locale.setDefault(Locale.ENGLISH); setze und initComponent aufrufe kommen die neuen Buttons in der anderen Sprache...
Allerdings sind die alten mit der alten Sprache auch noch da :shock:


----------



## bygones (3. Sep 2007)

um mal hoffentlich entwirrung zu bringen hier...

es wird von zwei dingen geredet.

1. Zum start des programmes wird eine sprache festgelegt, diese wird waehrend der laufzeit des programmes nicht mehr geaendert

2. Die Sprache wird waehrend der Laufzeit hin und her geandert.


zu 1. das kann man einfach wie schon erwaehnt ueber die ressource bundles loesen.
zu 2. das koennte FenchelT loesung schaffen, aber ich halte dies fuer unnoetig und overkill. Wie schon Wildcard meinte - dies ist keine generische loesung, mag fuer kleine entwicklungen ausreichen, aber nicht fuer typische software entwicklungen usw.

ehrlich gesagt versteh ich auch nicht, warum man waehrend der laufzeit die sprache aendern sollte ?!


----------



## Angel4585 (3. Sep 2007)

:roll: ich sagte ja auch das man das Programm beenden kann.
Aber es geht auch ohne indem ich einfach die geöffneten Formulare schliesse und neu erzeuge, da die Sprache automatisch bei der initialisierung des Formulars geladen wird.

Wenn ich es jetzt aber schaffe alle Controls auf dem Formular zu zerstören und über die initComponent die NetBeans automatisch erzeugt wieder zu erzeugen, dann müsste ich das nicht tun.


----------

