newInstance() von GUI-Klassen

… bereitet mir nun kopfzerbrechen. Das Problem ist, dass newInstance eine neue GUI baut. Logischerweise, das soll die Klasse ja auch im Anwendungsfall. Ich muss aber über Reflections an die Methoden dieser Klasse, damit ich via invoke() diese testen kann. Das Problem an der GUI ist eigentlich das EXIT_ON_CLOSE. Denn schließe ich die GUI, beendet sich auch mein Programm. Und das ist wahrlich nicht erwünscht. Meine Frage ist also,

  • ob es auch was anderes als invoke gibt, um die Klassenmethoden auszuführen
  • oder ob ich die neue Instanz in ihrem Tun einschränken kann.

Nochmal am Rand. Ich schreibe ein Programm zum automatisierten Testen fremder Klassendateien (von Schülern erstellte).
Bis jetzt kann ich alle Klassen einlesen, auflisten und kompilieren lassen. Das Testen wollte ich mit JUnit machen. Das geht aber nicht, weil zum Kompilierzeitpunkt alle Tests bekannt sein müssen*. Mein Programm braucht aber die Möglichkeit den Test instant zu erstellen. Darum muss ich jetzt über invoke die Methoden testen. Invoke will aber eine Instanz der Klasse. Und das heißt, die Klasse wird gestartet. Jedenfalls bei mir. Falls mir jemand Hinweise geben kann, wäre ich sehr verbunden.

  • Das war nur die grobe Erklärung. In der Tat ginge das schon. Ich habe mir schon Klassen während des Ausführens erstellt, kompiliert und gestartet. Das konnte ich aber für JUnit-Klassen nicht so ohne weiteres. Was am import des JUnit-Pakets liegt. Das wäre extern einzubinden und somit noch mehr Aufwand diese Klassen zu kompilieren. Mich würde wirklich mal interessieren, wie Softwarefirmen mit JUnit arbeiten. Da dort die Tests zuerst erstellt werden, haben sie nicht das gleiche Problem wie ich. Bei mir ist der Fluss sogesehen umgedreht. Meine Tests werden anhand der vorliegenden Klassen gebaut. Und nicht die vorliegenden Klassen anhand der Tests.

Nochmal schrittweise: Du hast irgendeine Klasse, z.B. sowas wie


class GUI extends JFrame
{
    public GUI()
    {
        getContentPane().add(someButton);
        ...
        setVisible(true);
    }
}

Davon erstellst du eine Instanz, und rufst dann ALLE (!?) Methoden auf? Sollen nicht nur einzelne, bestimmte Methoden aufgerufen werden? (Im Zweifelsfall die, die NICHT von JFrame geerbt wurden?). An welcher Stelle kommt da die DefaultCloseOperation zum Tragen?

EDIT: Oder geht es quasi im das Testen mehrerer solcher Instanzen - so dass du nur der Reihe nach die Aufpoppenden Instanzen schließen musst (dabei aber NICHT die Applikation beendet werden soll)? Da könnte man sich was überlegen. Entweder was “krudes”, dass man die Tests in eigenen JVMs startet (mit Runtime.exec), oder dass man als erstes eben setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) auf den Instanzen aufruft…

Letzteres ist mein Problem. Gut erkannt. Ich will natürlich nur einzelne Methoden testen. Aber newInstance() erstellt automatisch die ganze Klasse und startet sie auch durch. Mir wärs natürlich auch lieber, wenn ich ohne dem arbeiten könnte. Aber die Invokemethode benötigt eindeutig eine Instanz der zu testenden Klasse.

Hmja :confused: so ganz kapier’ ich’s immer noch nicht… Du erstellst eine Instanz. Dann poppt das Fenster auf. Du willst aber eigentlich nicht das Fenster, sondern nur ein paar Methoden auf dieser Instanz aufrufen. Du kannst aber das Fenster nicht schließen, weil dann die gesamte Anwendung beendet wird?

Kann man nicht auf der Instanz dann einfach „setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE)“ aufrufen und sie mit der Maus zumachen, oder ganz direkt gleich „setVisible(false)“ aufrufen?

deinen Erklärungen zufolge hast du es verstanden :wink: genau so verhält es sich.
Ok, vllt. kann ich ya, das Versteckenevent auslösen, aber das hilft mir auch nicht unbedingt, da dann die Instanz den Speicher vollspammt. Also von einer optimalen Lösung ist das noch weit entfernt. Ich werds morgen mal ausprobieren. Danke soweit

Um zu verhindern, dass der Speicher vollgemüllt wird, kann man gui.dispose() verwenden (oder geben DISPOSE_ON_CLOSE, wenn man’s manuell machen will). Dann sollte eigentlich alles aufgeräumt werden. Sag’ nochmal bescheid, falls es nicht klappt…

So einfach gehts dann doch nicht. Wenn ich eine neue Instanz der MainKlasse erstelle, erstellt diese dann wiederum eine Instanz der GUI-Klasse. Wie aber soll ich da so ohne weiteres rankommen? Zumal ich, wenn ich dispose nutzen will, die Instanz erstmal zu einem JFrame casten müsste. Ganz so trivial ist es nicht… :confused:

Ähm… geht es da jetzt konkret um Fälle, wo die GUI-Klasse NICHT der JFrame ist?


class GUI
{
    public GUI()
    {
        JFrame f = new JFrame();
        f.setVisible(true);
    }
}

Das könnte dann in der Tat etwas … fummeliger werden, aber vielleicht auch nicht: Mit http://java.sun.com/j2se/1.4.2/docs/api/java/awt/Frame.html#getFrames() kann man sich notfalls alle Frames holen, und die einfach alle zumachen…