KeyListener,MouseListener,MouseMotionListener und static

J@ckWhiteIII

Mitglied
Hallo,
ich hab mal eine Frage: Und zwar habe ich im folgendem Code das Problem, dass ich, wenn ich von einer Klasse mit den drei Oben genannten Interfaces auf public Variablen in einer anderen Klasse zugreifen will, ich diese immer static setzen muss. Das führt jedoch meistens zu irgendwelchen anderen Problemen. Darum meine Frage: Warum muss dabei alles static?
Hier der Code:
Java:
import javax.swing.*;

public class JumpnRun extends JApplet {
	
	private static final long serialVersionUID = 1L;
	public Screen screen; //müsste static, sonst kann ich von der Mouse Klasse nicht darauf zugreifen
	
	public void init(){
		screen = new Screen(this);
		add(screen);
	}
	
	public void start(){
		screen.running = true;
	}
	
	public void stop(){
		screen.running = false;
	}

}

Java:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class Screen extends JPanel implements ActionListener,Runnable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public int x,y;
	public Thread t = new Thread(this);
	public Character c = new Character(40,40,32,32);
	public boolean running = true;
	
	public Screen(JumpnRun frame){
		x = frame.getSize().width;
		y = frame.getSize().height;
		t.start();
		this.addMouseListener(new Mouse());
		this.addMouseMotionListener(new Mouse());
		this.addKeyListener(new Mouse());
	}

	public void actionPerformed(ActionEvent e) {
		
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		g.fillRect(0, 0, x, y);
		c.draw(g);
	}

	public void run() {
		while(true){
			if(running){
				repaint();
			}else{
				
			}
		}
	}

}

Java:
import java.awt.event.*;

public class Mouse implements MouseListener,MouseMotionListener,KeyListener{

	public void mouseDragged(MouseEvent e) {
		
	}

	public void mouseMoved(MouseEvent e) { //hier drin wollte ich auf screen in Klasse JumpnRun zugreifen..
		e.getX(); 
		e.getY();
	}

	public void mouseClicked(MouseEvent e) {
		
	}

	public void mouseEntered(MouseEvent e) {
		
	}

	public void mouseExited(MouseEvent e) {
		
	}

	public void mousePressed(MouseEvent e) {
		
	}

	public void mouseReleased(MouseEvent e) {
		
	}

	public void keyPressed(KeyEvent e) {
		
	}

	public void keyReleased(KeyEvent e) {
		
	}

	public void keyTyped(KeyEvent e) {
		
	}

}

Java:
import java.awt.*;
import javax.swing.*;

public class Character extends Rectangle {

	private static final long serialVersionUID = 1L;
	private Image img = new ImageIcon("C://Users//Marius//Pictures/Character1.png").getImage();
	
	public Character(int x, int y, int width,int height){
		setBounds(x,y,width,height);
	}
	
	public void draw(Graphics g){
		g.drawImage(img, x, y, width,height,null);
	}

}

Wäre nett, wenn jemand dazu eine Erklärung geben könnte. Dankeschön.
 
naja weil du immer nen Objekt der Klasse brauchst wenn du die "public" Variablen benutzen willst.
Wenn du direkt drauf zugreifen willst musst du diese als Static- Variablen machen. Übrigens sind public- Attribute keine schöne Lösung! 🙂
 
Wenn es in der falschen Klasse ist, frage ich mich jedoch, wo es sonst hinein soll, wenn nicht in die Hauptklasse.

Es wäre generell mal ganz schön, wenn auf diesem Forum z.B. ein Tutorial dafür gemacht würde, welches sich damit beschäftigt, wie man "sauberen" Code schreibt (habe bisher keins gefunden). Denn wenn man der OOP neu ist und auch nicht gerade studiert, ist es ziemlich schwer "Do's" und "Don't's" zu finden. Man sieht nämlich öfters auf diesem Forum, dass die Strukturierung vom Code des Threaderstellers kritisiert wird ("Dein Code ist ein völliges Chaos.", "was soll den der ganze static scheis"). Da es im AWT/Swing-Bereich dieses Forums ja eine Anleitung für's Zeichnen gibt, wäre es doch ganz schön, wenn es im Anfängerteil eine Strukturanleitung mit Regeln geben würde?
Musste einfach mal gesagt werden. Denn so wie es jetzt ist, sind Nichtstudierte verloren. Schade eigentlich, wo es doch ein schönes Forum ist.

Ist nicht böse gemeint, die Kritik, aber es scheint ja keiner selbst auf die Idee zu kommen.
 
Wenn es in der falschen Klasse ist, frage ich mich jedoch, wo es sonst hinein soll, wenn nicht in die Hauptklasse.
Die simple Antwort ist: Felder gehören immer in die Klasse, in der sie benutz werden, und es sollte immer nur eine Klasse geben, die ein Feld benutzt.

Und die Klasse mit der
Code:
main
Methode ist nicht zwangsläufig die Hauptklasse.

Es wäre generell mal ganz schön, wenn auf diesem Forum z.B. ein Tutorial dafür gemacht würde, welches sich damit beschäftigt,
Zu dem Thema gibt es genug Bücher. Wir wollen deren Autoren ja nicht verhungern lassen... ;o)

bye
TT
 
Dein einziges Problem ist eingentlich, dass du die Listener in eine eigene Klasse auslagerst. Um dann an die Screen-Instanz zu kommen müsstest du die Variable im Konstruktor von Mouse übergeben und in einer eigenen Instanzvariable (quasi nochmal) speichern. Das wäre zumindestens aus OOP-Sicht bei dieser Klassenaufteilung die beste Lösung.
Um diesen ganzen Zirkus zu vermeiden, ist es gängige Praxis, Listener als Anonyme/Innere Klassen zu implementieren, da dann diese Referenz implizit vorhanden ist (über Screen.this). Das wird vom Compiler zwar genauso umgesetzt, wie wenn man es selber in einer eigenständigen Klasse programmieren würde (über eine private Variable mit Namen this$0), aber der Code ist wesentlich leserlicher.
 
Soooooooo ich habe die Klasse Mouse gelöscht und Screen zum Folgenden verändert:

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Screen extends JPanel implements Runnable {
	
	private static final long serialVersionUID = 1L;
	public int x,y;
	public Thread t = new Thread(this);
	public CCharacter c = new CCharacter(40,40,32,32);
	public boolean running = true;
	
	public Screen(JumpnRun frame){
		x = frame.getSize().width;
		y = frame.getSize().height;
		t.start();
		frame.addMouseListener(new MouseAdapter(){
			
		});
		frame.addMouseMotionListener(new MouseMotionAdapter(){
			
		});
		frame.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent e){
				switch(e.getKeyCode()){
				case KeyEvent.VK_SPACE:           //springen
					if(!c.jumping){
						c.jumping = true;
					}
					break;
				case KeyEvent.VK_DOWN:          //ducken
					c.y += 2;
					break;
				case KeyEvent.VK_LEFT:
					c.x -= 2;
					break;
				case KeyEvent.VK_RIGHT:
					c.x += 2;
					break;
				}
			}
		});
	}
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		g.fillRect(0, 0, x, y);
		c.draw(g);
	}

	public void run() {
		while(true){
			if(running){
				c.jump(c.jumping);
				repaint();
			}else{
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

Allerdings wird c.jumping noch nicht true, d.h. ich werde daran noch arbeiten müssen. Der CCharacter lässt sich jedoch bewegen, was sehr gut ist. Vielen Dank an den letzten Post, da dieser mich von einer (schlechten) Angewohnheit abgebracht hat.
 

Zurück
Oben