AWT Wie kann ich ein Frame von einem anderen aus beeinflussen?

Diskutiere Wie kann ich ein Frame von einem anderen aus beeinflussen? im AWT, Swing, JavaFX & SWT Bereich.
D

DingDong

Hallo,
ich bin bei einer Aufgabe zum Thema MVC und Frames schier am verzweifeln. Es soll ein Mosaikspiel programmiert werden.
Bei einem Mausklick auf ein Spielfeld sollen die umgebenden Spielfelder umgedreht werden. Zeitgleich soll in einem
Protokollfenster mit gleichem Mosaikmuster nur das angeklickte Feld umgedreht werden. Ein Beispiel:

Spielfläche:__________ Protokollfläche
1 2 3__________________1 2 3
4 5 6__________________4 5 6
7 8 9__________________7 8 9

Wenn in der Spielfläche die 3 angeklickt wird, sollen die Felder 2, 5 und 6 umgedreht werden. Zeitgleich soll auf der Protokollfläche das
Feld 3 umgedreht werden.
Leider gelingt es mir nicht, bei einem Klick auf das Spielfeld eine Reaktion auf dem Protokollfeld zu erzeugen. Vielleicht habt ihr ja
einen Tipp für mich. Den Code hab ich in gezipptem Format angehängt.

Viele Grüße

Enzo

PS: Die untere Linien hab ich eingefügt, da Leerzeichen nicht angezeigt wurden.
 

Anhänge

mihe7

mihe7

PS: Die untere Linien hab ich eingefügt, da Leerzeichen nicht angezeigt wurden.
Verwende Code-Tags (die drei Punkte neben dem Smiley, dort Code).

Zur Frage (habe mir jetzt Deinen Code nicht angesehen): das Model enthält ja das Mosaik, das Spielfeld zeigt das Model an. Dazu registriert sich das Spielfeld beim Mosaik als Beobachter. Sobald das Mosaik aktualisiert wurde, werden alle registrierten Beobachter über dieses Ereignis informiert. Für die Darstellung des Spielfelds reicht als Ereignis ein einfaches "hey, die Inhalte des Mosaiks haben sich geändert". Für das Protokoll brauchst Du halt noch eine Zusatzinfo "hey, die Inhalte des Mosaiks haben sich geändert, weil der Benutzer das Feld x,y umgedreht hat". Fertig.
 
D

DingDong

Wenn ich nur wüsste, wie ich dieses
"hey, die Inhalte des Mosaiks haben sich geändert"
und
"hey, die Inhalte des Mosaiks haben sich geändert, weil der Benutzer das Feld x,y umgedreht hat".
in Code übertragen wird bzw. wo mein Fehler liegt.
Das Mosaik wird in diesem Programm nicht in den Modell-Klassen aufgebaut, sondern in 3 Klassen. Eine Klasse erzeugt das Frame, die zweite Klasse ein Panel und die dritte die Spielfelder über Canvas-Objekte.
Folgendes habe ich bis jetzt versucht:

Code:
package programme;

import interfaces.ModelIF;
import klassen.*;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;

public class Mosaik extends Frame {

    // C:\Users\vince\Documents\SGD_Kurse\Software_Entwickler\JAV04\Frühlingsblume.PNG

    private Color farbeRueckseite, farbeVorderseite;
    private StatistikModel statistik;
    int raster;
    private ArrayList<Point> pt;
    //private ProtokollFenster protokollFenster;
    private ProtokollFenster protokollFenster;
    private ProtokollModell protokollModell;
    private MosaikModel mosaikModel;
    private MosaikEventHandler eventHandler;
    protected ModelIF protokollIF;

    public Mosaik(int r) {

        pt = new ArrayList<>();

        // Neues Frame für Aufgabe 4
        protokollFenster = new ProtokollFenster(r, true);
        protokollFenster.setLocation(400, 0);// Positionierung des Frames neben dem Spieleframe

        // Spieleparameter
        this.raster = r;
        farbeRueckseite = new Color(230, 30, 50);
        farbeVorderseite = new Color(50, 210, 30);

        //Spielfläche
        FarbMosaik fm = new FarbMosaik(raster, getSize().width, farbeRueckseite, farbeVorderseite);
        statistik = new StatistikModel();
        mosaikModel = new MosaikModel(raster, raster);
        protokollModell = new ProtokollModell(raster, raster, farbeRueckseite, farbeVorderseite);

        fm.getEventHandler().addModel(statistik);

        /*Die nächste Anweisung fügt zwar dem EventHandler das
        * ProtokollModell hinzu, erzeugt leider eine NullpointerE.
        * todo: klasse ProtokollModell so verändern, dass eine Aktion
        *  im ProtokollFenster erzeugt wird*/
        fm.getEventHandler().addModel(protokollModell);

        setVisible(true);
        setSize(300, 300);
        add(fm);

        //dieser Methodenaufruf bewirkt ein Schließen
        //des Frame-Fensters
        this.addWindowListener(new WindowAdapter() {
            public void windowClosing( WindowEvent ev )
            {
                pt = statistik.getPt();
                for (int i = 0; i < pt.size(); i++){
                    System.out.println("Zeile: " + pt.get(i).x + ", Spalte: " + pt.get(i).y);
                }

                System.out.println("Anzahl Versuche: " + pt.size());
                dispose();
                System.exit( 0 );
            }
        });
    }

    public static void main(String[] args) {

        int ra;
        if(args.length == 0)
            ra = 3;
        else
            ra = Integer.parseInt(args[0]);

        Mosaik mkl = new Mosaik(ra);
        int x = mkl.getWidth() + 20; // Abstand zum Spieleframe
    }
}
Ich habe in der Frame-Klasse dem EventHandler aus der Panel_klasse das Modell des Protokoll-Frames über
Code:
 fm.getEventHandler().addModel(protokollModell);
hinzugefügt.
Dadurch sollte bei einem Klick auf ein Spielefeld die action-Methode der Klasse ProtokollModell aufgerufen werden, wobei das entsprechende Protokollfeld umgedreht werden sollte.

Code:
package klassen;

import interfaces.ModelIF;
import interfaces.MosaikIF;

import java.awt.*;

public class ProtokollModell implements ModelIF {

    MosaikIF[][] mObjects;
    Color farbeRueckseite, farbeVorderseite;
    int zeilen, spalten;

    public ProtokollModell(int zeilen, int spalten, Color farbeRueckseite, Color farbeVorderseite) {
        this.zeilen = zeilen;
        this.spalten = spalten;
        this.farbeRueckseite = farbeRueckseite;
        this.farbeVorderseite = farbeVorderseite;
        mObjects = new ProtokollCanvas[zeilen][spalten];
    }

    public void switchNachbarn(int zeile, int spalte) {
        // erste Zeile: Mitte, links, rechts
        invert(zeile,spalte);

    }

    private void invert(int zeile, int spalte) {

        getMObj(zeile, spalte).switchSeite();// für ein MosaikCanvas-Objekt
        System.out.println("ProtokollModell invert");
    }

    @Override
    public void action(int zeile, int spalte) {
        this.invert(zeile, spalte);
        System.out.println("ProtokollModell action");
        System.out.println("Zeile = " + zeile);
        System.out.println("Spalte = " + spalte);
    }

    @Override
    public void putMObj(int zeile, int spalte, MosaikIF mObj) {
        mObjects[zeile][spalte] = mObj;
        System.out.println("ProtokollModell putMObj");
    }

    @Override
    public MosaikIF getMObj(int zeile, int spalte) {
        System.out.println("ProtokollModell getMObj");
        return mObjects[zeile][spalte];
    }
}
Leider bekomme ich bei einem Klick auf ein Spielfeld eine Nullpointer-Exception, da aus irgendeinem Grund, den ich nicht verstehe, das zu übertragende Objekt null ist.
Code:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at klassen.ProtokollModell.invert(ProtokollModell.java:30)
    at klassen.ProtokollModell.action(ProtokollModell.java:36)
    at klassen.MosaikEventHandler.mouseReleased(MosaikEventHandler.java:42)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
    at java.desktop/java.awt.Component.processEvent(Component.java:6401)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Vielen Dank für eure Hilfe und Grüße
Enzo
 
D

DingDong

Ja, das ist im Studienheft so vorgegeben. Meine Aufgabe ist es, das Protokollfenster zu programmieren.
 
mihe7

mihe7

OK, da muss man erstmal halbwegs durchblicken. Das Model implementiert die ModelIF-Schnittstelle und hält Objekte mit MosaikIF-Schnittstelle, die ihrerseits die Schnittstelle zum UI ist.

Das "hey, die Inhalte des Mosaiks haben sich geändert, weil der Benutzer das Feld x,y umgedreht hat" ist also bereits berücksichtigt.

Das ProtokollModel muss sich vom MosaikModel nur dahingehend unterscheiden, dass in action() ein anderer Code ausgeführt wird. Das hast Du bereits.

Was Du auch tun musst: das ProtokollModel beim MosaikEventListener registrieren (addModel()). Das sollte eigentlich alles sein.
 
D

DingDong

Was Du auch tun musst: das ProtokollModel beim MosaikEventListener registrieren (addModel()). Das sollte eigentlich alles sein.
Das hatte ich in der Frame-Klasse Mosaik gemacht. Funktioniert leider trotzdem nicht.
 
D

DingDong

Hab das Problem gelöst 🧐. Der Fehler war, dass ich den MosaikEventHandler 2 mal instanziiert hatte.
 
Thema: 

Wie kann ich ein Frame von einem anderen aus beeinflussen?

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben