Reflection Problem

roxX0r

Mitglied
Hallo,

Es geht um folgendes: ich möchte der GUI meines Programmes weitere Sprachen gönnen, die Dialoge und Labels usw. werden aus einer XML Datei ausgelesen und je nach Sprache, sollen diese gesetzt werden.
Mein Ansatz lautet:

Gehe über alle Objekte der GUI Klasse und falls du eine Objekt findest, welches so heißt wie ein EIntrag in der XML Datei, dann setze den Wert aus der XML Datei.
Also in der XML Datei steht vereinfacht drin:

id=jButton1
lang=de
value=Das ist das Caption meines Buttons in Deutsch


Wobei die id genau der Variablenname des betreffenden Buttons ist.

Java:
      public void changeLang() {

        // c ist die Klasse in der die ganzen GUI Elemente (Buttons usw.) definiert sind.
        Class c = HotkeyGUI.class;
        try {
            // er läuft über alle Elemente in der XML Datei (hab ich vorher schon geparst)
            for (String key : MessageParser.map.keySet()) {
                
                // über alle Felder der Klasse (also auch GUI Elemente)
                for (Field field : c.getDeclaredFields()) {
                    
                    // wenn die Variable mit dem passenden Namen gefunden worden ist
                    if (field.getName().equals(key)) {

                        // hole dir die Methode setText von dem JButton
                        Method method = field.getType().getMethod("setText", String.class);
                        //und setze den Wert (vorher aus der XML geparst)
                        method.invoke(field, MessageParser.map.get(key));

                    }


                }
            }

        } catch (Exception e) {
            System.out.println(e);
            e.printStackTrace();
        }


    }


So nun bekomm ich hier eine "java.lang.NoSuchMethodException: javax.swing.JButton.setText(java.lang.String)"

Was mach ich falsch?

Irgendwie müsste ich das Objekt bekommen, das ich ändern möchte. Aber ich habe nur seinen Variablennamen als String vorliegen (bzw. als 'Field' Objekt). Wie kann ich nun direkt an das Objekt rankommen?
 
Zuletzt bearbeitet:
Mir würde spontan folgendes einfallen:

Du definiertst ein Interface, z.B. 'LocaleGUIElement'.
In dieses kommt der Methodenrumpf 'setLocaleText(String text)'.
Jedes GUI Element, daß du mit der geparsten XML Datei lokalisieren willst, implementiert dein Interface 'LocaleGUIElement'
In die Methode kommt der Aufruf, den Text zu setzen.

Wenn Du jetzt den Variablennamen deines GUI Elementes hast, ist es wurst, was für eins es ist, ganz sicher ist es
aber ein Object vom Typ 'LocaleGUIElement'. Und dafür ist die Methode 'setLocaleText(String text)' auf jeden Fall definiert.

Hatti
 
hallo Hatti,

ja das ginge in der Tat. Mein Progamm hat aber unzählige GUI Elemente in verschiedenen Klassen, ich würde das gern irgendwie über Reflections machen, da ich nicht alle GUI Klassen ändern möchte.

Also der Ansatz, so wie ich es schon habe, so sollte es doch irgendwie auch gehen?
 
schwierig zu sagen, weil
1. der Inhalt von HotkeyGUI nicht bekannt ist
2. Ich mich mit Reflection eh nicht so auskenne 🙂

Das Method.invoke funktioniert nur bei Klassen, die bereits instantiiert sind (ggf. nicht bei statischen Methoden, aber 'setText' ist definitiv keine). Also benötigt man die instantiierte Klasse, aud die man das .invoke ausführt. Bislang hast du die nicht.
Wenn die HotkeyGUI als Felder die instantiierten Buttons
Java:
public javax.swing.JButton meinButton=new javax.swing.JButton("Mein Text");

hat, dann könnte man vielleicht mittels

Java:
Object value=Field.get(Object obj);
if(value instanceof javax.swing.JButton)
{
...
}
vielleicht an das "laufende" Objekt herankommen.
Was fehlt, ist jetzt noch das Object obj, dass dem Field.get übergeben werden muss. Für statische Felder darf das null sein, für nicht statische Felder benötigt es wiederum eine instantiierte Klasse.
In deinem Fall die HotkeyGUI. In Zeile 4 deines Beispieles wird jedoch nur die Klasse selbst ermittelt, nicht die bereits instantiierte Klasse.
Ohne diese sehe ich keinen weiteren Erfolg.

Wenn die HotkeyGUI Klasse nur das Object selber definiert

Java:
public Class meinButton=javax.swing.JButton.class;

Dann sehe ich noch viel schwärzer, weil die Reflection nicht ermitteln kann, welches das konkrete Objekt ist, welches sie ändern soll.

Hatti
 
Hatti! Super klasse, es läuft!

Und zwar so:

Java:
Object value = field.get(this);
if(value instanceof javax.swing.JButton){
  javax.swing.JButton b = (javax.swing.JButton)value;
  b.setText("test");
}

"this" ist in diesem Falle das Object der Klasse HotkeyGUI.

Ich hab mit der "Get" Funktion des field Objektes schon rumgespielt, hab aber nich kapiert, was das Object sein soll, das als Parameter übergeben werden soll. Jetzt hab ichs geschnallt, der brauch natürlich das Object von dessen Klasse das gewünscht Feld-Objekt gefunden werden soll....

Danke nochmal 🙂
 

Neue Themen


Zurück
Oben