MouseListener funzt net.

Status
Nicht offen für weitere Antworten.

siddy1981

Mitglied
also Syntaktisch ist alles klar aber ich habe kein plan wieder der MouseListener nix tut... 🙁
also der soll bei klick nen Point per DrawPoint.DrawPoint(e.getX(), e.getY(), actualcolor); zeichnen...
debugtechnisch in der Main aufrufen funktioniert es aber per mouselistener nicht...
was mach ich da falsch ???


hier der code

Code:
package guiGo2;
/*DrawWindow.java*/

import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsDevice;
import java.awt.Window;
import javax.swing.JFrame;
import java.awt.MouseInfo.*;
import java.awt.event.*;
import java.awt.event.MouseListener;

public class DrawWindow implements Runnable, MouseListener {

    private static int win_width,  win_height,  field_h,  field_w;
    static Graphics g;
    static Color actualcolor;
    static Window myWindow;
    static JFrame F = new JFrame("Go");
    static DrawField drawField = new DrawField(400, 400);

    DrawWindow() { // konstruktor
        this.win_height = 500;
        this.win_width = 600;
        this.field_h = 400;
        this.field_w = 400;
        this.actualcolor =Color.RED; // SET DEFAULTCOLOR  FOR DEBUGGING       
    }

    public void run() {
        F.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        F.setSize(win_width, win_height);
        F.setVisible(true);        
        F.addMouseListener(this);
    }

    @SuppressWarnings("static-access")
    public static void main(String[] args) {
        (new Thread(new DrawWindow())).start();
        drawField.setLayout(null);
        F.add(drawField);
            DrawPoint.DrawPoint(80, 100, Color.BLUE);  //debugging point... klappt wunderbar 
    }

    public void mouseClicked(MouseEvent e) {
        //drawpoint only debugging um zu wissen ob der hässliche Mouselistener funzt
        DrawPoint.DrawPoint(e.getX(), e.getY(), actualcolor);  
        //        setArray[e.getX()][e.getY()] = "PLAYER";   
        /* eigentlich diese vorläufige nicht angepasste anweisung...  
         *  muss e.getxy muss aber noch ans array angepasst werden... 
         *sonst ist compiler böse... ;)
        **/
    }

    public void mousePressed(MouseEvent e) {
// NOP();
    }

    public void mouseReleased(MouseEvent e) {
// NOP();
    }

    public void mouseEntered(MouseEvent e) {
// NOP();
    }

    public void mouseExited(MouseEvent e) {
// NOP();
    }
}
 
hier hab ich noch mal drawfield und drawpoint ->

Code:
package guiGo2; 
/* 
* DrawPoint.java 
*/ 
import java.awt.*; 
import javax.swing.*; 

public class DrawPoint extends JLabel { 

    private Color color = Color.RED; 

    public DrawPoint(int x, int y,Color c) { 
        setBounds(x, y, 20, 20); 
       this.color =c;
    } 

    public void drawPoint(int x, int y) { 
        setLocation(x, y); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        Graphics2D g2D = (Graphics2D) g; 
        g2D.setColor(color); 
        g2D.fillOval(0, 0, 20, 20); 
    } 
     

public static void DrawPoint(int x, int y, Color c){
    
DrawWindow.drawField.add(new DrawPoint(x, y,c));

}

}


Code:
package guiGo2; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import javax.swing.*; 
import java.awt.*; 
/*DrawField.java*/
public class DrawField extends JPanel { 
Color lineColor = Color.BLACK; 
Color background = Color.GRAY; 

    public DrawField(int x, int y) { 
        this.setSize(x, y); 
        this.setBackground(background); 
    } 
    

    @Override 
    public void paintComponent(Graphics g) { 
        super.paintComponent(g); 
        Graphics2D g2D = (Graphics2D) g; 
        for (int i = 0; i <= 400; i += 20) { 
            g2D.setColor(lineColor); 
            g2D.drawLine(i, 400, i, 0); 
            g2D.drawLine(400, i, 0, i); 
        } 

    } 
}

aber sonst nein getgraphics rufe ich nicht auf...
dachte dass muss ich auch nicht weil sonst alles funktioniert...
 
Mit diesem static-murks kann ja auch niemand rechnen..

DrawWindow.drawField.add(new DrawPoint(x, y,c));
DrawWindow.drawField.validate();
DrawWindow.drawField.repaint();
 
ahhh thanks... es funzt.... und jetzt die frage : wieso static murks ??
wie könnte man es denn besser machen ?? bzw effektiver ??
 
Ganz allgemein sollte man fields "fast nie" static machen. Das ist keine Objektorientierte Modellierung (im eigentlichen Sinn). Stell dir nur mal vor, du willst irgendwann mal zwei DrawFields nebeneinander anzeigen (ist aber auch nur ein Beispiel).

Ein kleiner Ausflug, weil mit langweilig ist... war: Eine Modellierung, die in dem Sinne "gut" ist, dass sie skalierbar und sehr allgemein anwendbar ist (und schließlich will man ja i.a. nicht ein Spiel schreiben, sondern was lernen, was man später noch brauchen kann) ist das Model-View-Controller-Pattern (MVC-Pattern).

Du könntest dein Go schreiben, und das GUI komplett ignorieren. Schreib' dein Spiel als Spiel als Spiel und nur als Spiel. Überleg' dir, welche Eigenschaften (fields, "Zustandsbescheibungen") das Spiel hat, und welche Methoden ("Aktionen") es geben soll. Überleg' dir, was man braucht, um das Spiel quasi vollständig(!) "fernsteuern" zu können:
Code:
class Go
{
    // Speichert die Felder (leer, schwarz, weiß)
    private int board[][] = ... 

    // Der Spieler, der gerade dran ist
    private int activePlayer = ...

    // Noch mehr Eigenschaften 
    ....

    // Welcher Spielstein auf Feld (x,y) liegt
    public int getColorAt(int x, int y) { ... }

    // Setzt den gegebenen Spielstein bei (x,y) 
    public void setColorAt(int x, int y, int stone) { ... }

    // Wer gewonnen hat
    public int getWinner() { ... }

    // Noch mehr Methoden
    ....
}
Das ist nur ur Vedeutlichung! Ich kenne Go nicht richtig, und WAS man genau braucht, um es vollständig zu beschreiben, muss DU dir überlegen!

Wenn das Spiel dann fertig ist, kann man es auf verschiedene Arten bedienen. Entweder, indem man es "programmatisch" laufen läßt:
Code:
Go go = new Go();
go.setColorAt(3,4, Go.BLACK);
go.setColorAt(1,2, Go.WHITE);
go.setColorAt(5,4, Go.BLACK);
if (go.gameOver()) printSomething();
oder indem man es an der Konsole spielen läßt
Code:
Go go = new Go();
int x;
int y;
while (!go.gameOver())
{
    x = benutzerEingabe("Schwarz: Gib x ein");
    y = benutzerEingabe("Schwarz: Gib y ein");
    go.setColorAt(x,y, Go.BLACK);

    x = benutzerEingabe("Weiss: Gib x ein");
    y = benutzerEingabe("Weiss: Gib y ein");
    go.setColorAt(x,y, Go.WHITE);
}
oder - was du willst - mit einem GUI
Code:
// Visualisiert das Spielfeld
class GoPanel extends JPanel
{
    private Go go = ...

    // Zeichne das Brett (oder füge entsprechend Buttons in das Panel ein, oder sonstwas)
    public paintComponent(Graphcis g)
    {
        for (alle Positionen) 
        {
            if (go.getColorAt(x,y) == Go.WHITE) maleWeiss();
            if (go.getColorAt(x,y) == Go.BLACK) maleSchwarz();
            if (go.getColorAt(x,y) == Go.EMPTY) maleNix();
        }
    }
}

// Kontrolliert den Spielablauf, bzw. empfängt Benutzereingaben und leitet sie an Go weiter
class GoController implements ActionListener oder MouseListener
{
    private Go go = ...

    public GoController()
    {
        ...
        goPanel.addActionOderMouseListener(this);
        ...
    }

    void spiele()
    {
        while (!go.gameOver())
        {
            erwarteBenutzerEingabe();
            goPanel.aktualisiereMitNeuemZustand();
        }

    }

    public void actionPerformed(ActionEvent e)
    {
        int x = findeRausWasGeklicktWurdeX();
        int y = findeRausWasGeklicktWurdeY();
        go.setColorAt(x,y, farbe);
    }

    
}

Nochmal: Insebsondere den GUI-Teil jetzt NICHT alles einfach rauskopieren, und versuchen, "mit Leben zu füllen". Das soll wirklich nur der Verdeutlichung des Konzepts dienen: Ein Spiel kann für sich selbst exisiteren, und gespielt werden. Das GUI dient dann nur dem Zweck
1. den aktuellen Spielzustand anzuzeigen (wie auch immer: Mit buttons, oder kleinen JPG-Bilchen von Steinen oder so)
2. Benutzereingaben zu empfangen, und an das "abstrakte" Spiel weiterzuleiten

Wenn du da dann noch ein bißchen geschickte Objektierientierung reinbringst, wird das ganze sogar recht flexibel...
Code:
abstract class Player
{
    private int color;
    abstract Move doMove(Go go);
}
class HumanPlayer extends Player { ... }
class ComputePlayer extends Player { ... }
class NetworkPlayer extends Player { ... }
So dass es ggf. sogar zwei menschliche Spieler geben kann, die auf dem gleichen GUI (oder verschiedenen GUIs, es ist ja nichts static :wink: ) spielen, oder übers Netzwerk, oder oder oder... Aber das nur als Anregung, damit du weißt, womit du dich die nächsten Monate beschäftigen könntest :wink:
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben