FXML - Internationalisierung - Behandung key not found

Joob

Top Contributor
Ich baue gerade in mein Projekt Sprachbundels ein.

Dabei gibt es ein Problem, wenn ein Key im FXML nicht gefunden wird, stürzt die App ab.
Gibt es eine Möglichkeit dort immer einen Standardwerte einzusetzen ?
Also das FXML dazu zu bringen das wenn der Key nicht gefunden wird einfach an der Stelle ein ? einzusetzen .

Beim Jasper wird dann einfach null ausgegeben, so was wäre für mich OK
 

Joob

Top Contributor
Meine Frage bezieht sich nur auf die Behandlung dieser Exception die im FXML ausgelöst wird.


Hier ist die Exception.
Mein Problem ist das ich diese nicht behandeln kann.
Oder gibt es eine Möglichkeit das in der Stage zu überschreiben ?

Es muss doch möglich sein,
dort im Falle eines fehlenden Schlüssels,
einen Standardwert auszugeben,
und so die Anzeige des FXML zu gewährleisten.


Oder geht das nicht, das würde mir stundenlanges Suchen ersparen und ich würde grundsätzlich nach einer anderen Lösung suchen.

javafx.fxml.LoadException: Resource "FXMLYou.label.yourname" not found.
/C:/Users/Jupp/Documents/NetBeansProjects/VTDESKTOP/build/resources/main/VIEWS/You.fxml:86
/C:/Users/Jupp/Documents/NetBeansProjects/VTDESKTOP/build/resources/main/VIEWS/AppStart.fxml:14

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.resolvePrefixedValue(FXMLLoader.java:432)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:370)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:332)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:242)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:775)
at javafx.fxml/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2838)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2557)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1154)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at org.joobsoft.vt.CONTROLLER.LoginController.handle_CB_LOGIN(LoginController.java:217)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8890)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.keyReleased(ButtonBehavior.java:161)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$KeyHandler.process(Scene.java:4070)
at javafx.graphics/javafx.scene.Scene.processKeyEvent(Scene.java:2121)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2597)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
at javafx.graphics/com.sun.glass.ui.View.handleKeyEvent(View.java:547)
at javafx.graphics/com.sun.glass.ui.View.notifyKey(View.java:971)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:830)
 

Flown

Administrator
Mitarbeiter
Wie lädst du dein FXML? Du könntest dir dein eigenen ResourceBundle Wrapper schreiben. Wenn dein Key nicht gefunden wurde, dann liefer doch dein default.
 

krgewb

Top Contributor
Bitte immer in Code-Tags posten.
Java:
javafx.fxml.LoadException: Resource "FXMLYou.label.yourname" not found.
/C:/Users/Jupp/Documents/NetBeansProjects/VTDESKTOP/build/resources/main/VIEWS/You.fxml:86
/C:/Users/Jupp/Documents/NetBeansProjects/VTDESKTOP/build/resources/main/VIEWS/AppStart.fxml:14

at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.resolvePrefixedValue(FXMLLoader.java:432)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processValue(FXMLLoader.java:370)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:332)
at javafx.fxml/javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:242)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:775)
at javafx.fxml/javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2838)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2557)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader$IncludeElement.constructValue(FXMLLoader.java:1154)
at javafx.fxml/javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:754)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at org.joobsoft.vt.CONTROLLER.LoginController.handle_CB_LOGIN(LoginController.java:217)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1784)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8890)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:203)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.keyReleased(ButtonBehavior.java:161)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$KeyHandler.process(Scene.java:4070)
at javafx.graphics/javafx.scene.Scene.processKeyEvent(Scene.java:2121)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.keyEvent(Scene.java:2597)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:217)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$KeyEventNotification.run(GlassViewEventHandler.java:149)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleKeyEvent$1(GlassViewEventHandler.java:248)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleKeyEvent(GlassViewEventHandler.java:247)
at javafx.graphics/com.sun.glass.ui.View.handleKeyEvent(View.java:547)
at javafx.graphics/com.sun.glass.ui.View.notifyKey(View.java:971)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:830)
 

dzim

Top Contributor
Naja, dein Default-Resource-Bundle sollte eben die Default-Werte enthalten. Ich glaube nicht, dass du das umgehen kannst.

Die einzige Variante, die mir einfällt (weil ich sie so verwende), die aber deutlich mehr Arbeit benötigt: Kümmer dich um die zu Übersetzenden Text selbst. Lade dein Resource Bundle, lade deinen Key und wenn es Fehler gibt, zeige es entsprechend an (wir zeigen dann den Key in Ausrufezeichen umhüllt an - !my.notexistent.key!).
Da wir auf Änderungen der Sprache innerhalb der Applikation hören, ist der Ansatz kein Problem. Halt nur mit mehr Arbeit verbunden.
 

mihe7

Top Contributor
Gibt es eine Möglichkeit dort immer einen Standardwerte einzusetzen ?
Wie @dzim schon sagte: Default-Bundle -> Default-Werte :) Allerdings könntest Du das Default-Bundle als Klasse zur Verfügung stellen, die den Basename des Bundles trägt und sich im richtigen Package befindet:

Java:
package i18n;
import java.util.*;

public class Values extends ResourceBundle {

    public Enumeration<String> getKeys() {
        return Collections.enumeration(new HashSet<String>());
    }

    public String handleGetString(String key) {
        return (String) handleGetObject(key);
    }

    public Object handleGetObject(String key) {
        return "!" + key + "!";
    }
}

Code:
my.label=Test

Java:
import java.util.*;

public class Test {

    public static void main(String[] args) {
        ResourceBundle bundle = ResourceBundle.getBundle("i18n.Values");
        System.out.println(bundle.getString("my.label"));
        System.out.println(bundle.getString("my.label.wtf"));
    }
}

Code:
Test
!my.label.wtf!
 

Joob

Top Contributor
Hallo,

tut mir leid das ich erst jetzt reagieren kann, aber ich habe meine Resourcedatei geschrieben.
Das war sehr viel Arbeit.

Erst mal danke, für die Vorschläge.
Aber das habe ich schon umgesetzt gehabt.

Das Problem ist das fxml, dem das Resourcenpaket mitgegeben wird. Ich normalen Quellcode habe ich eine Ausnahme definiert die angezeigt wird wenn der Key nicht gefunden wird.

Aber im FXML habe ich keinen Einfluss auf die Behandlung eines nicht gefundenen Keys.

Pane loginPane = (Pane)FXMLLoader.load(getClass().getResource("/VIEWS/Login.fxml"), getLangbundel());

Über getLangbundel wird das Resourcenpaket an das FXML .

Ich müsste irgendwo in der pane, der scene oder sonst wo angeben wie mit einem solchen Fehler umgegangen werden soll.
Ich hatte ja geschrieben das jasperreport für nicht gefundene Resourcen einfach null anzeigt,
wenn ich das im fxml umsetzen könnte wäre mir geholfen.

Die Frage ist nur wie kann ich einen solchen Fehler dort abfangen und eine Standardwert angzeigen.
 

Joob

Top Contributor
Ja, hatte ich erst übersehen.

Aber ich habs noch nicht kapiert.

wie kommen die Methoden aus Values in das Resourcebundel
oder warum verwendet man die Klasse Values nicht
und wie sag ich dem Bundel welches propfile es laden soll.
 

mihe7

Top Contributor
Das ResourceBundle erhält die Werte entweder aus .properties-Files oder aus Klassen. Wenn Du ein Bundle "strings" hast, und die Locale en_UK gilt, dann werden die Werte zunächst in strings_en_UK, dann in strings_en und dann in strings gesucht, die eben entweder als .properties-File oder als Klasse vorliegen können.

Wenn das Bundle "strings" heißt, muss die Klasse Values in strings umbenannt werden.
 

Joob

Top Contributor
Ich verstehe trotzdem noch nicht was da abgeht.

Deine Klasse Values ist das Default Bundle.
Wenn ein Key im aktuellen Bundel nicht gefunden wird, wird diese Klasse aufgerufen.
Im DefaultBundel gibt es nur die Fehlerbehandlung.
Damit wird dann der Wert ausgegeben.

Aber wie gebe ich die strings_de_DE.properties an das Bundel welches ich verwende ?
Also bei dir das Values_de.properties

Zu den Voraussetzungen noch:
die Klasse strings (bei dir Values) muss im Resourcenordner der Sprachproperties liegen, bei mir
also Languages
12966


Lieg ich da mit irgend etwas richtig oder ist alles Quatsch.
Bitte zeig mir doch wo ich die Zusammenhängen nachlesen kann.
 

Joob

Top Contributor
Ich glaube ich weis was ich falsch gemacht habe.
Ich hab immer die strings_de_DE.properties so in das Bundel gesetzt.
Also
ResourceBundle.getBundle(strings_de_DE.properties)
weil ich noch nicht richtig verstehe wie das funktioniert mit dem _de_DE
 

mihe7

Top Contributor
Also
ResourceBundle.getBundle(strings_de_DE.properties)
weil ich noch nicht richtig verstehe wie das funktioniert mit dem _de_DE
Wenn Du erst jedesmal angeben müsstest, welche Locale geladen werden soll, wäre der Spaß ja ziemlich uninteressant. Das Ding heißt Bundle, weil es eben die Werte für mehrere Locales zur Verfügung stellt. Daher darfst Du auch nur den Basename angeben, bei Dir also "LANGUAGES.strings".
 

Joob

Top Contributor
Ich hab das jetzt aufgeteilt und die Klasse strings die du mir gezeigt hast in meinem Ordner eingefügt.

12975

Das haut aber nicht hin. Werden denn im ResourceOrdner unter Gradel die Klassen überhaupt kompliert.

Oder hab ich irgendwas ganz falsch verstanden.
So definier ich mein Bundel. Ich habe die Bezeichnung des Bundels in einer Datenbank stehen und zwar mit vollem Namen deshalb
zerlege ich es bevor ich es in der App über eine statische Klasse zur Verfügung stelle.

Code:
String[] languagesparts;
        languagesparts = _basepropfile.split("_");
        Locale localapp = new Locale (languagesparts[1], languagesparts[2]);
        _baselangbundel= ResourceBundle.getBundle(languagesparts[0], localapp);

in der statischen Klasse habe ich sowieso für nicht gefundene Keys eine Behandlung.
Ausserdem ist meine APP unglaublich langsam geworden seit ich Local mitgebe.

Kannst du mir helfen und zeigen wo ich was falsch mache ?
 

mihe7

Top Contributor
Die Datei strings.java wirst Du vermutlich nicht unter Ressourcen sondern normal im src-Folder (allerdings auch dort im Paket LANGUAGES) ablegen müssen.

Java:
ResourceBundle.getBundle(languagesparts[0], localapp);
Ein einfaches ResourceBundle.getBundle("LANGUAGES.strings"); sollte reichen.
 

dzim

Top Contributor
Convention-over-Configuration kann ganz schön strange sein... :D

Um ehrlich zu sein: Ich kannte diesen Weg nicht einmal! o_O (Klassenname = Resourcendateiname)
 

Joob

Top Contributor
@mihe7 ;

Hallo,

ich habe das jetzt ganz anders vor.
Ich hatte ja gesagt das ich eine Klasse für zur Verfügungstellung der Strings aus dem Sprachbundel geschrieben habe.

Die Sache mit dem FXML ist mir zu unübersichtlich.
Ich habe jetzt angefangen überall in den FXML wieder Texte einzutragen, damit ist das FXML klarer für Veränderungen.
Im Controller habe ich jetzt eine Methode in der ich die Klasse für Strings, oben erwähnt verwende um die Bezeichnungen zu ändern, damit wird je nach Sprachpaket entsprechend umgestellt und ich hab die Fehlerbehandlung in der Hand.

Bevor ich jetzt wieder tagelang ändere, würde ich gerne deine Meinung hören.
Hab ich da was übersehen oder kann man das so machen.
Bin mal auf die Performance gespannt, aber ich glaube da tut sich nicht viel, zumal das FXML so keine Sprachbundel braucht.

Wäre nett wenn du mich warnst das ich nicht nach der ganzen Änderei an einer nicht bedachten Stelle auf die Nase falle und alles wieder zurückändern muss.
 

dzim

Top Contributor
@Joob Auch @Robat ist hier ein treuer Ratgeber... :p

Ich bin mir nicht zu 100% sicher, ob ich deine Frage verstanden habe. Es macht schon Sinn nur *ein* ResourceBundle zu haben - ob es bei kleinen Anwendungen schon einen spürbaren Einfluss hat... Keine Ahnung.
Aber um besser darauf eingehen zu können, mach mal ein Code-Beispiel, dann wissen wir mehr.
 

Joob

Top Contributor
Hallo bin in der Woche nicht immer online, deshalb die verspätete Antwort.

Mein grundsätzliches Problem war es das wenn ich dem FXML ein ResourceBundel mitgebe und ein Schlüssel in dem Bundel fehlte das Fenster nicht angezeigt wurde.

Die Lösung von MiHe7 mit der Klasse als Resourcebundel fand ich nicht so gut, weil die Klasse nur in scr kompiliert wird. Da ist meine Projektstruktur betroffen und das will ich nicht.

Ich hatte mir aber schon eine staitsche Klasse geschrieben die den Text aus dem ResourceBundel ausgibt und wollte diese Klasse dann im Controller verwenden um die Nods mit dem Text zu initalisieren.

Das hab ich jetzt fertig.
Ich sehe da den Vorteil das ich in der Klasse einen Wert ausgeben kann wenn der Key nicht gefunden wird, und das Fenster in jedem Fall angezeigt wird.

Was hälst du davon ?
 

Joob

Top Contributor
Weil ich gradel verwende und es keinen zwingenden Grund gibt die übersichtliche Struktur aufzubrechen, denn es müsste ein Packages Languages dort direkt unter scr/main verwendet werden, wenn ich es richtig verstanden habe.
 

mihe7

Top Contributor
Weil ich gradel verwende und es keinen zwingenden Grund gibt die übersichtliche Struktur aufzubrechen, denn es müsste ein Packages Languages dort direkt unter scr/main verwendet werden, wenn ich es richtig verstanden habe.
Du kannst die Sprachdateien auch in ein Paket legen, das es bereits gibt. Aber selbst, wenn man das nicht machen will, sehe ich keinen Grund, Programmieraufwand zu betreiben, nur damit man sich nicht an einem Paket stört.
 

Joob

Top Contributor
Aber wenn ich alles über eine Klasse regeln kann, ist das doch viel einfacher.
Ich habe das schon umgesetzt und es läuft gut, soweit ich das beurteilen kann.

Ich hab halt nach eine Lösung gesucht, würde aber gerne verstehen was gegen die Lösung spricht.
Das ist meine Klasse, nur zum Verständnis, ich schreibe ein Protokoll, da kann dann also die Sprache von der Benutzersprache abweichen. Deshalb gibt es eine Benutzersprache und eine Appsprache.



Code:
public class LanguageProvider {
    
    private static String _propuserlangfile = "";
    private static String _propapplangfile = "";
    private static ResourceBundle _langbundel;
    private static ResourceBundle _baselangbundel;
    private static HashMap _jaslanghasmap;
    

    // Festlegen der SprachProp
    public static void setProplangfile(String _propfile) {
        
        try {
            LanguageProvider._propuserlangfile = _propfile;
            
            // Language bundel
            _langbundel = ResourceBundle.getBundle(_propfile);


            // Jasper
            _jaslanghasmap = new HashMap();
            _jaslanghasmap.put ("REPORT_RESOURCE_BUNDLE", _langbundel);

            System.setProperty("SYSLA", _propfile);
        
        } catch (Exception ex) {
            
            // Nicht übersetzen Sonderfall Languagefile not present
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("Language file");
            alert.setHeaderText("File is missing : " + _propfile);
            alert.setContentText("Please install the app once more ! \n\n" + ex);
            DialogPane dialogPane = alert.getDialogPane();
            alert.showAndWait();
            
        }
    }
    
    public static void setBaseProplangfile (String _basepropfile) {
        _baselangbundel= ResourceBundle.getBundle(_basepropfile);
        _propapplangfile = _basepropfile;
    }

//    // Baselanguage file from Baselanguage /Maintenance for logfile
//    public static ResourceBundle getBaselangbundel() {
//        return _baselangbundel;
//    }
    
    

    // Getter
    public static String getbaselangfile() {
        return _propapplangfile;
    }
    
    public static String getuserlangfile() {
        return _propuserlangfile;
    }
        
    public static HashMap getJaslanghasmap() {
        return _jaslanghasmap;
    }
        
    // für die Auswahl des Textes in strings....properties
    public static String getlangstring(String keyofstring) {
        
        String langstr = "!" + keyofstring + "!";
        try {
            langstr = _langbundel.getString(keyofstring);
        } catch (Exception ex) {
            System.out.println("UserLanguage - Parameter unkonwon : " + keyofstring );
        }
        return langstr;
    }
    
    // Baselanguage aus Maintenance für log
    public static String getbaselangstring(String keyofstring) {
        
        String langstr = "!" + keyofstring + "!";
        try {
            langstr = _baselangbundel.getString(keyofstring);
        } catch (Exception ex) {
            System.out.println("SystemLanguage - Parameter unkonwon : " + keyofstring );
        }
        return langstr;
        
    }
  
}
 

Joob

Top Contributor
Ist es nicht OK die Klasse static zu machen, damit wird sie nur einmal geladen und steht der ganzen Anwendung zur Verfügung.
 

mihe7

Top Contributor
Welchen Automatismus meinst du ?

Was ist mit Framework gemeint ?
JavaFX ist das Framework, auf dem Du Deine Anwendung aufbaust, und mit Automatismus ist gemeint, dass JavaFX mit FXML sich bereits automatisch um die Internationalisierung kümmert. So wie ich Dich verstanden habe, willst Du sämtliche Texte nun manuell setzen.

Alternativ kannst Du ja auch einen Decorator verwenden (s. Kommentar #3 von @Flown bzw. Dein Kommentar aus #8 dürfte in die Richtung gehen).

Ist es nicht OK die Klasse static zu machen, damit wird sie nur einmal geladen und steht der ganzen Anwendung zur Verfügung.
Statisch und konstant wäre vertretbar, statisch und variabel (globally shared mutable state) ist Mist. Das kann gut gehen, ist aber eine fragile Angelegenheit, weil theoretisch von überall aus, zu jedem Zeitpunkt das Bundle geändert werden kann. Wenn Du da nicht höllisch aufpasst, lädst Du plötzlich aus einem falschen Bundle die Werte. In die Klasse dann auch noch UI-Code unterzubringen, rundet das Fiasko ab.
 

Joob

Top Contributor
Zum ersten:
Ja, ich muss auf jeden Fall in jedes Feld den BundleKey einsetzten.
Jedoch bei meiner Lösung kann ich erst Standardwerte einsetzen, dadurch ist das Formular erst mal besser lesbar.
Im Controller setze ich dann nur die Zeile: Beispiel:

columnBaseLanguage.setText(getlangstring("FXMLTVWords.tab.header.baselanguage"));

das ist doch total übersichtlich, und die Klasse reagiert auf einen eventuell fehlenden Key.
Dann brauche ich doch den ganzen Automatismus nicht mehr, oder.

Den zweiten Teil habe ich nicht verstanden.
Ich hatte mir gedacht, es gibt eine staitische Klasse. Die Bundles werden in die Klasse geladen und sind somit überall in der App verfügbar.

Kannst du mir das Problem was ich erzeugt habe genauer erklären.
Was könnte ich falsch machen um ein Problem zu erzeugen, oder gibt es ein Sicherheitsproblem ?
Die Bundels werden bei Appstart einmal geladen, so wie sie in der DB gespeichert sind, danach werden aus diesen wie oben beschrieben nur noch die Texte geladen.
Ich habe das so gemacht und hatte erst Sorge das das nicht gut läuft, hat sich aber als übersichtlich erwiesen.
Aber wie gesagt, wäre nett wenn du dir Mühe machst mir die Defizite zu zeigen.
 

mihe7

Top Contributor
Jedoch bei meiner Lösung kann ich erst Standardwerte einsetzen, dadurch ist das Formular erst mal besser lesbar.
Das ist richtig, zumindest, was das XML betrifft. Hier muss man auf die Wahl geeigneter Keys achten. Der Scene Builder zeigt Dir aber die übersetzten Werte an (s. https://docs.oracle.com/javafx/scenebuilder/1/user_guide/i18n-support.htm)

Im Controller setze ich dann nur die Zeile: Beispiel:

columnBaseLanguage.setText(getlangstring("FXMLTVWords.tab.header.baselanguage"));
Ja, doppelte Arbeit halt und wenn Du die Zeile vergisst, wird der Wert gar nicht übersetzt :)

Kannst du mir das Problem was ich erzeugt habe genauer erklären.
Das habe ich doch beschrieben:
theoretisch von überall aus, zu jedem Zeitpunkt das Bundle geändert werden kann. Wenn Du da nicht höllisch aufpasst, lädst Du plötzlich aus einem falschen Bundle die Werte.
Etwas abstrakter: durch die Nutzung einer globalen Wertes hängt Dein Code von diesem Wert ab. Das ist ok, wenn der Wert eine Konstante ist (z. B. im Fall von Math.PI). Ist er aber variabel, kann eine Zeile an irgendeiner Stelle die gesamte Anwendung "kaputt" machen. Das Verhalten des Codes ist nicht mehr vorhersagbar.
 

Joob

Top Contributor
Kann man denn von außen an der Anwendung etwas ändern ? (Die Konstante kann ich doch nur im Code ändern oder ?)

Wieso ist das Verhalten nicht vorhersehbar. Der Languageprovider tut doch seinen Job wie jeder andere Code auch. Wo siehst du den Unterschied ?

Entschuldige bitte die Fragen, aber ich hab mir Java über verschiedene Quellen angeeignet, dabei in der Regel konkrete Probleme gelöst. So was wie bekomme ich Daten aus einer Datenbank, wie baue ich das in meine App ein ohne zuviel Aufwand zu haben. Aber ich habe das Gefühl das mir da etwas Entscheidenes für mein Verständnis fehlt.

Die App läuft stabil und ich habe sie im Rahmen der Erstellung auch schon einige Male komplett erweitert, das klappt alles gut.
 

mihe7

Top Contributor
aber ich hab mir Java über verschiedene Quellen angeeignet,
Das hat nichts mit Java zu tun.

Nehmen wir mal an, Du wohnst in einer Wohnung und möchtest in der Küche die Lampe wechseln. Du nimmst also, um ganz sicher zu gehen, die Hauptsicherung raus und verziehst Dich mit der Taschenlampe in die Küche.

Kommt jetzt Deine Freundin nach Hause, merkt, dass im Gang das Licht nicht geht und drückt mal eben die Sicherung wieder rein, dann wirst Du evtl. verstehen, was "nicht vorhersehbar" bedeutet :p
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
MiMa Darstellung von FXML ateien nicht korrekt (SceneBuilder) AWT, Swing, JavaFX & SWT 2
Jose05 Aus einer normalen Java Klasse eine FXML-Klasse laden AWT, Swing, JavaFX & SWT 12
Georges456 NetBeans am Mac leider ohne FXML AWT, Swing, JavaFX & SWT 17
R Fxml findet controller nicht AWT, Swing, JavaFX & SWT 2
thor_norsk JavaFX, FXML und SceneBuilder AWT, Swing, JavaFX & SWT 6
Jose05 JavaFx Fxml: GUI aus einer anderen Klasse starten AWT, Swing, JavaFX & SWT 1
K Bekomme (u.a) javafx.fxml.LoadException trotz "korrektem" Code AWT, Swing, JavaFX & SWT 8
G JavaFX Wert aus DB lesen, wenn erfolgreich automatisch eine fxml laden, möglich? AWT, Swing, JavaFX & SWT 2
N Braucht man fxml AWT, Swing, JavaFX & SWT 3
S Fehler beim Öffnen weiterer FXML AWT, Swing, JavaFX & SWT 11
Jose05 JavaFX: eigene FXML-Datei für einen Button AWT, Swing, JavaFX & SWT 3
M mvvm umsetzen ohne fxml AWT, Swing, JavaFX & SWT 0
L JavaFX .fxml laden klappt nicht AWT, Swing, JavaFX & SWT 16
T FXML Datei in Java Code einbinden: javafx.fxml.LoadException AWT, Swing, JavaFX & SWT 2
J JavaFX - Included FXML - Entfernen feststellen AWT, Swing, JavaFX & SWT 2
L JavaFX javafx.fxml.LoadException bei einem Taschenrechner AWT, Swing, JavaFX & SWT 5
G JavaFX Verständnisfrage mit parametrisierten Methoden und FXML AWT, Swing, JavaFX & SWT 21
Ø Ein FXML-File mehrfach einfügen AWT, Swing, JavaFX & SWT 6
MiMa Schliessen eines FXML Fensters? AWT, Swing, JavaFX & SWT 10
OSchriever Auf Stage von FXML-Controller zugreifen AWT, Swing, JavaFX & SWT 12
L JavaFX Exception nach includieren einer fxml // nested controller AWT, Swing, JavaFX & SWT 1
R FXML File kann nicht hinzugefügt werden! AWT, Swing, JavaFX & SWT 2
J import javafx.fxml* bei JavaFX 13 geht nicht mehr AWT, Swing, JavaFX & SWT 7
S JavaFX Variablen in einem FXML File verwenden AWT, Swing, JavaFX & SWT 8
T Fxbefehle aus Main umwandeln in @FXML AWT, Swing, JavaFX & SWT 21
L JavaFX JavaFX, FXML und Guice? AWT, Swing, JavaFX & SWT 0
H 3 verschiedene Nachrichten in einer FXML View die Infos kommen aus DB AWT, Swing, JavaFX & SWT 4
H JavaFX Probleme Beim Wechseln der scene als .fxml AWT, Swing, JavaFX & SWT 7
TheWhiteShadow JavaFX Dependencies in fxml AWT, Swing, JavaFX & SWT 17
M JavaFX Altes Fenster (FXML Datei) löschen AWT, Swing, JavaFX & SWT 16
R JavaFX Java FXML Vererbung in Klassen AWT, Swing, JavaFX & SWT 9
F Java FX Von der Fxml Datei zum Objekt AWT, Swing, JavaFX & SWT 8
F FXML Datei aus dem SceneBuilder in Eclipse aufrufen AWT, Swing, JavaFX & SWT 1
I MediaPlayer (MediaView) in FXML (source) AWT, Swing, JavaFX & SWT 0
I FXML: StackPane als Root-Element AWT, Swing, JavaFX & SWT 5
I Bild über FXML (ImageView, Image) anzeigen AWT, Swing, JavaFX & SWT 1
MiMa Übergeben von Paramter bei FXML Aufruf? AWT, Swing, JavaFX & SWT 8
MiMa Wie bettet man Programmcode in JavaFX FXML ein? AWT, Swing, JavaFX & SWT 34
H Java FX List<AlbumsBean> in FXML TableView AWT, Swing, JavaFX & SWT 37
B FXML GUI - Button ausblenden AWT, Swing, JavaFX & SWT 1
D JavaFX Einbinden einer .fxml AWT, Swing, JavaFX & SWT 1
S java.fxml.load.exception und keine automatische Aktualliseriung der Mainausgabe AWT, Swing, JavaFX & SWT 5
L JavaFX Zugriff auf HostServices im FXML Controller AWT, Swing, JavaFX & SWT 1
T Pfad zur *.fxml AWT, Swing, JavaFX & SWT 8
D Java FXML mehrere Fenster AWT, Swing, JavaFX & SWT 4
Ernesto95 JavaFX FXML vs. Java Code AWT, Swing, JavaFX & SWT 3
L Liniendiagramme mit FXML: Quellen mit konkreten Beispielen AWT, Swing, JavaFX & SWT 0
S JavaFX fxml datein mit menübar ändern AWT, Swing, JavaFX & SWT 20
K JavaFX JavaFX und FXML AWT, Swing, JavaFX & SWT 6
F Problem mit der FXML Rectangle Shape AWT, Swing, JavaFX & SWT 2
H JavaFX aus der .fxml Datei einen Konstruktor bedienen AWT, Swing, JavaFX & SWT 3
H JavaFX via .fxml einen abgeleiteten Button erstellen... AWT, Swing, JavaFX & SWT 4
E Java FX FXML Problem mit html Scriptausführung AWT, Swing, JavaFX & SWT 2
R Java FX - Fxml - relative Größenangaben für Breite und Höhe einer TextArea AWT, Swing, JavaFX & SWT 8
U JavaFX Zeichenprogramm mit JavaFX FXML AWT, Swing, JavaFX & SWT 7
B Java FX FXML Textarea SceneBuilder als XML Editor AWT, Swing, JavaFX & SWT 1
C JavaFX Tiefgestellte Zeichen in fxml AWT, Swing, JavaFX & SWT 2
M Java FX SceneBuilder 2.0, FXML, Controller AWT, Swing, JavaFX & SWT 1
B FXML-Layoutdateien schützen AWT, Swing, JavaFX & SWT 4
7 JavaFX Verwendung einer ResizableCanvas-Klasse in fxml-Datei AWT, Swing, JavaFX & SWT 3
C JavaFX Auf Nodes einer FXML-Datei in start Methode zugreifen AWT, Swing, JavaFX & SWT 5
KrokoDiehl JavaFX Gleiche Controller-Instanz für inludiertes FXML AWT, Swing, JavaFX & SWT 1
I Scene Builder kann .fxml nicht mehr laden AWT, Swing, JavaFX & SWT 3
S JavaFX FXML-Editor mit Java 7? AWT, Swing, JavaFX & SWT 2
J JavaFX Zugriff auf FXML-Variablen eines anderen Controllers AWT, Swing, JavaFX & SWT 2
X Java Fxml laden AWT, Swing, JavaFX & SWT 4
N JavaFX GUI Elemente einer anderen (FXML)Klasse ansprechen AWT, Swing, JavaFX & SWT 16
M JavaFX FXML Standartgröße festlegen AWT, Swing, JavaFX & SWT 5
L JavaFX Verständnisfrage zu JavaFX FXML und Controller-Klasse AWT, Swing, JavaFX & SWT 1
Z JavaFX Inhalt einer ViewTable durch Aktion einer Menubar ändern welche in einer anderen fxml ist AWT, Swing, JavaFX & SWT 4
wolfgang63 JavaFX Zugriff auf Guiobjekte die über FXML erstellt wurden AWT, Swing, JavaFX & SWT 2
D JavaFX @FXML Annotation mit Klassen und Instanzen verbinden? AWT, Swing, JavaFX & SWT 5
A Databinding in FXML-Datei AWT, Swing, JavaFX & SWT 1
K JavaFX Erzeugen dynamischer Layouts in fxml AWT, Swing, JavaFX & SWT 3
M JavaFX Stage in einer FXML-Controllerklasse ermitteln? AWT, Swing, JavaFX & SWT 5
G Swing, JavaFx - Felder aus FXML sind null AWT, Swing, JavaFX & SWT 6
M JavaFX Von FXML-Controllerdatei Daten zurückgeben AWT, Swing, JavaFX & SWT 6
M Komplexe Eingabenmasken in FXML definieren? AWT, Swing, JavaFX & SWT 17
M Java FX Innerhalb einem FXML-Dialog weiteren FXML-Dialog einblenden AWT, Swing, JavaFX & SWT 3
E JavaFX fxml files wechseln AWT, Swing, JavaFX & SWT 4
H Taschenrechnerprojekt in Javafx - Frage zu den Buttons in FXML AWT, Swing, JavaFX & SWT 1
T JavaFX FXMLController für mehrere FXML? AWT, Swing, JavaFX & SWT 7
M JavaFX Parameter für Custom Control in FXML übergeben? AWT, Swing, JavaFX & SWT 4
C JavaFX Fxml and stylecheets AWT, Swing, JavaFX & SWT 5
N FXML Dokument laden AWT, Swing, JavaFX & SWT 1
Tort-E JavaFX FXML Grundsatzfrage AWT, Swing, JavaFX & SWT 2
K Controls in Controls / Nested fxml AWT, Swing, JavaFX & SWT 1
D JavaFX Mysteriöser Dropshadow hinter Tablabelschrift - Schatten kann nicht entfernt werden (FXML + CSS) AWT, Swing, JavaFX & SWT 6
G JavaFX NullPointerException bei Zugriff auf FXML Element AWT, Swing, JavaFX & SWT 0
S JavaFX FXML AWT, Swing, JavaFX & SWT 3
G JavaFX Fxml AWT, Swing, JavaFX & SWT 2
K JavaFX Tableview mit fxml ohne Aktualiserung trotz Thread AWT, Swing, JavaFX & SWT 13
F JavaFX Auf FXML ImageView zugreifen AWT, Swing, JavaFX & SWT 6
S Aus XML Datei FXML generieren AWT, Swing, JavaFX & SWT 4
B JavaFX FXML - Eclipse einrichten AWT, Swing, JavaFX & SWT 2
V JavaFX - fxml-Datei laden (neben CSS) AWT, Swing, JavaFX & SWT 2
dzim UI aus FXML und Java gemischt - NPE? AWT, Swing, JavaFX & SWT 4
V Guis erstellen mit FXML und javaFX gemischt AWT, Swing, JavaFX & SWT 5
D JavaFX Internationalisierung zur Laufzeit AWT, Swing, JavaFX & SWT 7
G Internationalisierung auf Knopfdruck AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben