Swing Flackern in Frame bei erstem Klick

lal000r

Mitglied
Hallo Leute,

ich bin neu hier und suche eine Lösung für ein kleines Problemchen, dem ich partout nicht auf die Schliche komme. Dieses Forum scheint mir dafür am geeignetsten. 😉

Folgende Situation:
Ich "muss" eine Art Schachspiel inkl. UI programmieren. Derzeit habe ich mehrere Model-Klassen, einige Mouselistener und eben die View mit Swing.

Ich weiß jetzt nicht genau, wie ich die gesamte Situation erklären soll, von daher versuche ich es mal möglichst einfach zu halten.
Die View stellt ein Schachbrett dar, auf welches Figuren entsprechend ihrem Vorhandensein in der Board-Klasse des Models gezeichnet werden. Das alles geschieht mit der paintComponent()-Methode, die ich überschreibe.
Ein repaint des Panels, welches das Spielbrett zeichnet, geschieht durch die unterschiedlichen Mouselistener, z.B. durch MouseReleased.
Das Problem bei mir ist, dass nur unter Windows XP, ein erstmaliges MousePress, also ein Klick und dann festhalten, das Flackern des Panels auslöst. Unter Windows 7 geschieht dies nicht. Außerdem ist es egal welche Java-Version zum Einsatz kommt. (Java 6 und 7 getestet)
Dies passiert wirklich nur beim allerersten Klick, danach nicht wieder.
Nachdem das Panel einmal geflackert hat, wird augenscheinlich sofort ein repaint() durchgeführt, obwohl ich diesen nicht durch MousePressed auslösen lasse.
Das alles ist sicherlich schwer zu erklären und auch schwer nachzuvollziehen, deswegen werde ich ein Video des gesamten Problems anfügen.

knightsjava - YouTube

Desweiteren ein bisschen Code, der hoffentlich verständlich ist. Ich bin noch nicht sonderlich geübt im sinnvollen Strukturieren, von daher bitte nicht alles niedermachen. 😀

Die Controller, also die Listener:

Java:
public class Mouselistener implements MouseListener{
	
	BoardGraphic panel;
	boolean hasPiece = false;

	public Mouselistener(BoardGraphic panel){
		this.panel = panel;
	}
	
	@Override
	public void mousePressed(MouseEvent event) {

		int xCoord = event.getX();
		int yCoord = event.getY();
//		panel.setDrawDragX(event.getX()); 
//		panel.setDrawDragY(event.getY()); 
		Game currentgame = GameManager.getInstance().getCurrentGame();
		
		if (xCoord > (this.panel.getWidth() / 2 - 280)
				&& xCoord < (this.panel.getWidth() / 2 + 280)
				&& yCoord > (this.panel.getHeight() / 2 - 280)
				&& yCoord < (this.panel.getHeight() / 2 + 280)) {
			
			panel.setIsDragging(true);
			
			int[] pos = this.panel.getPositionOnBoard(xCoord, yCoord);
			// Initialisieren der aktiven Spielfigur
			this.hasPiece = currentgame.getBoard().hasPiece(pos[0], pos[1]);
			if (this.hasPiece){
			panel.initActivepiece(new ActivePiece());
			panel.getActivepiece().setRow(pos[0]);
			panel.getActivepiece().setCol(pos[1]);
			panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0], pos[1]));
			
			panel.getActivepiece().setPossibleFields();
			panel.drawPossibleFields(panel.getGraphics());
			panel.markStartField(panel.getGraphics());
			
			panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0],pos[1]));
			currentgame.getBoard().setFieldPiece(panel.getActivepiece().getRow(), panel.getActivepiece().getCol(), currentgame.getBoard().getPieceEmpty());
			
			}
		}
		
	}

	@Override
	public void mouseReleased(MouseEvent event) {
		panel.setIsDragging(false);
		
		if(panel.getActivepiece() != null)
		{
		int xCoord = event.getX();
		int yCoord = event.getY();
		Game currentgame = GameManager.getInstance().getCurrentGame();
		// Prüfen ob Releasepunkt innerhalb des Feldes. Wenn wahr, dann neues
		// Feld mit Figur besetzen.
		if (xCoord > (this.panel.getWidth() / 2 - 280)
				&& xCoord < (this.panel.getWidth() / 2 + 280)
				&& yCoord > (this.panel.getHeight() / 2 - 280)
				&& yCoord < (this.panel.getHeight() / 2 + 280)) {


				// Position für das Board-Model ermitteln
				int[] pos = this.panel.getPositionOnBoard(xCoord, yCoord);
				// Figur setzen
				
				currentgame.getBoard().setFieldPiece(pos[0], pos[1],
						panel.getActivepiece().getPiece());

				panel.repaint();
				// Activepiece "leeren"
				panel.resetActivePiece();
				this.hasPiece = false;
			
		} // Falls Releasepunkt nicht innerhalb des Feldes, wird die Figur
			// wieder auf das Ausgangsfeld gesetzt.
		else {
			currentgame.getBoard().setFieldPiece(panel.getActivepiece().getRow(),
					panel.getActivepiece().getCol(),panel.getActivepiece().getPiece());
			panel.setIsDragging(false);
			panel.resetActivePiece();
			panel.repaint();
			
		}
	}
	}

}

Der MouseMotionListener:
Java:
public class MousemotionListener implements MouseMotionListener {

	ActivePiece activepiece;
	BoardGraphic panel;
	public MousemotionListener(BoardGraphic panel){
		this.panel=panel;
		this.activepiece=panel.getActivepiece();
	}
	
	@Override
	public void mouseDragged(MouseEvent event) {
		panel.setDrawDragX(event.getX()); 
		panel.setDrawDragY(event.getY()); 
		panel.repaint();
		
		
		
	}

Und die Klasse BoardGraphic (das Panel, in dem alles gezeichnet wird):
Java:
public class BoardGraphic extends JPanel {

	private static final long serialVersionUID = 1L;
	ActivePiece activepiece = null;
	boolean isDragging = false;
	int drawDragX, drawDragY = 0;
	final int CELLSIZE = 80;
	
	
	public BoardGraphic() {
		this.setPreferredSize(new Dimension(650, 600));
		this.setBackground(new Color(230, 230, 250));
		this.addMouseListener(new Mouselistener(this));
		this.addMouseMotionListener(new MousemotionListener(this));
		
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		int xStart = this.getWidth() / 2;
		int yStart = this.getHeight() / 2;
		this.setFont(g);
		
		
		for (int i = 0; i < 7; i++) {
			for (int j = 0; j < 7; j++) {
				if (i % 2 == 0) {
					if (j % 2 == 0) {
						g.setColor(new Color(105, 105, 105));
					} else {
						g.setColor(new Color(240, 230, 140));
					}
				} else {
					if (j % 2 == 0) {
						g.setColor(new Color(240, 230, 140));
					} else {
						g.setColor(new Color(105, 105, 105));
					}
				}
				g.fillRect(xStart - 280 + j * CELLSIZE, yStart - 280 + i * CELLSIZE, CELLSIZE, CELLSIZE);		
			}
		}
		// Zeilenbeschriftungen links
		for (int i = 1; i < 8; i++) {
			g.drawString(Integer.toString(i), xStart - 320, (yStart - 230) + (i - 1) * CELLSIZE);
		}
		// Zeilenbeschriftungen rechts
		for (int i = 1; i < 8; i++) {
			g.drawString(Integer.toString(i), xStart + 305, (yStart - 230) + (i - 1) * CELLSIZE);
		}
		//Spaltenbeschriftungen oben
		for (int i = 1; i < 8; i++) {
			char zwischen = (char) (i+96);
			g.drawString(Character.toString(zwischen), xStart-250 + (i-1)* CELLSIZE, yStart-310 );
		}
		//Spaltenbeschriftungen unten
		for (int i = 1; i < 8; i++) {
			char zwischen = (char) (i+96);
			g.drawString(Character.toString(zwischen), xStart-240 + (i-1)* CELLSIZE, yStart+320 );
		}
		
		drawPiece(xStart, yStart, g);
	
		if (this.isDragging == true && this.activepiece != null) {
			markStartField(g);
			drawPossibleFields(g);
			drawPieceWhileDragging(this.drawDragX, this.drawDragY, g);
		}
	}



	void drawPiece(int w, int h, Graphics g) {
		Game currentgame = GameManager.getInstance().getCurrentGame();
		int pieceStartX = (this.getWidth() / 2);
		int pieceStartY = (this.getHeight() / 2);

		for (int i = 0; i <currentgame.getBoard().getRows(); i++) {
			for (int j = 0; j < currentgame.getBoard().getCols(); j++) {
				if (currentgame.getBoard().getFieldPiece(i, j) == currentgame.getBoard().getPlayerAPiece()) {
					g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerAPiece()),
							(pieceStartX - 280) + j * CELLSIZE, pieceStartY - (280 - i * CELLSIZE), this);
				} else if (currentgame.getBoard().getFieldPiece(i, j) == currentgame.getBoard().getPlayerBPiece()) {
					g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerBPiece()),
							(pieceStartX - 280) + j * CELLSIZE, pieceStartY - (280 - i * CELLSIZE), this);
				}
			}
		}
	}
		
	
	void drawPieceWhileDragging(int drawDragX, int drawDragY, Graphics g) {
		
		Game currentgame = GameManager.getInstance().getCurrentGame();
		if (this.activepiece.getPiece() == currentgame.getBoard().getPlayerAPiece()) {
			// Mauszeiger folgen
			g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerAPiece()),
					drawDragX - 30, drawDragY - 30, this);
		}
		if (this.activepiece.getPiece() == currentgame.getBoard().getPlayerBPiece()) {
			// Mauszeiger folgen
			g.drawImage(loadPieceImages(currentgame.getBoard().getPlayerBPiece()),
					drawDragX - 30, drawDragY - 30, this);
		}
	}
	
	
	public int[] getPositionOnBoard(int xCoord, int yCoord) {
		Game currentgame = GameManager.getInstance().getCurrentGame();
		int xStart = this.getWidth() / 2;
		int yStart = this.getHeight() / 2;
		int[] position = new int[2];

		for (int i = 0; i < currentgame.getBoard().getRows(); i++) {
			for (int j = 0; j < currentgame.getBoard().getCols(); j++) {
				// Spalten!!
				if (xCoord > (xStart - 280) + j * CELLSIZE
						&& xCoord < (xStart - 280) + (j + 1) * CELLSIZE) {
					// Zeilen!!
					if (yCoord > (yStart - 280) + i * CELLSIZE
							&& yCoord < (yStart - 280) + (i + 1) * CELLSIZE) {

						position[0] = i;
						position[1] = j;
					}
				}
			}
		}
		return position;
	}
	
	
	public void drawPossibleFields(Graphics g) {

		for (int i = 0; i < this.activepiece.getPossibleFields().length; i++) {
			drawRectangles(this.activepiece.getPossibleFields()[i].getRow()-1,
					this.activepiece.getPossibleFields()[i].getCol() - 97, Color.GREEN, g);
		}
	}

	public void drawRectangles(int row, int col, Color color, Graphics g) {
		int xStart = this.getWidth() / 2;
		int yStart = this.getHeight() / 2;
			
		for (int j = 0; j < 4; j++) {
			g.setColor(color);
			g.drawRect((xStart - 280 + j) + (col) * CELLSIZE,
					(yStart - 280 + j) + (row) * CELLSIZE,
					CELLSIZE - 2 * j, CELLSIZE - 2 * j);
		}
	}
	
	public void markStartField(Graphics g) {
		drawRectangles(this.activepiece.getRow(), this.activepiece.getCol(), Color.BLUE, g);
		
	}
	
		
	Image loadPieceImages(char piece) {
		BufferedImage image = null;
		if (piece == GameManager.getInstance().getCurrentGame().getBoard().getPlayerAPiece()) {
			try {
				image = ImageIO.read(new File("pieces/jumper_black.png"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else if (piece == GameManager.getInstance().getCurrentGame().getBoard().getPlayerBPiece()) {
			try {
				image = ImageIO.read(new File("pieces/jumper_white.png"));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return image;
	}
	
	public ActivePiece getActivepiece() {
		return this.activepiece;
	}
	
	public void initActivepiece(ActivePiece activepiece) {
		this.activepiece = activepiece;
	}
	
	public boolean getIsDragging() {
		return this.isDragging;
	}

	public void setIsDragging(boolean isDragging) {
		this.isDragging = isDragging;
	}
	
	public void setDrawDragX(int drawDragX) {
		this.drawDragX = drawDragX;
	}

	public void setDrawDragY(int drawDragY) {
		this.drawDragY = drawDragY;
	}
	 public void resetActivePiece(){
		 this.activepiece = null;
	 }
	

	Font setFont(Graphics g){
		Font text;
		GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
		ge.getAvailableFontFamilyNames();
		text = new Font("Arial", Font.BOLD, 25);
		g.setFont(text);
		g.setColor(Color.black);
		return text;		
	}
}

Ich hoffe, das war jetzt nicht zu viel Code, aber da ich nicht weiß, was genau das Problem auslösen könnte, weiß ich nicht, wo ich etwas eingrenzen kann.
Ich danke schon einmal im Voraus für kompetente Hilfe! 🙂
 
Dein code sieht eigentlich ganz ok aus, wie fügst du dein BoardPanel in deinen Frame ein? Ich vermute dass da das Problem liegt.
 
Hallo,
danke für deine schnelle Antwort.
also das Panel wird folgendermaßen in ein anderes Panel eingefügt (Methode: addBoardGraphic())

Java:
public class MainPanel extends JPanel implements SwingConstants {

	private static final long serialVersionUID = 1L;
	
	
	

	public MainPanel() {
		super();
		this.setLayout(new BorderLayout());
		initLabels(this);
		addBoardGraphic();		
	}
	
	void initLabels(MainPanel panel){
		JLabel player1 = new JLabel("Spieler A:");
		player1.setHorizontalAlignment(CENTER);
		player1.setBackground(new Color(119,136,153));
		player1.setForeground(new Color(255,255,255));
		player1.setPreferredSize(new Dimension(0,50));
		player1.setOpaque(true);
		this.add(player1, BorderLayout.NORTH);
		
		JLabel player2 = new JLabel("Spieler B:");
		player2.setHorizontalAlignment(CENTER);
		player2.setBackground(new Color(255,255,224));
		player2.setForeground(new Color(0,0,0));
		player2.setPreferredSize(new Dimension(0,50));
		player2.setOpaque(true);
		this.add(player2, BorderLayout.SOUTH);			
	}

	void addBoardGraphic(){
		BoardGraphic graphic = new BoardGraphic();
		this.add(new JScrollPane(graphic), BorderLayout.CENTER);
	}

Aber warum tritt das Problem dann nur unter Windows XP auf? Und warum wird ein repaint() ausgelöst? :bahnhof:
 
Ich glaube nicht dass da ein repaint ausgelöst wird, sondern dass deine addBoardGraphic Methode nochmal ausgeführt wird. Mach mal ein System.out in die Methode und prüf das mal.
 
Wäre schön gewesen, aber die Ausgabe erfolgt nur einmal und zwar beim Starten der View. Dann müsste mir das Problem auch vorher schon aufgefallen sein, aber irgendwie so um den Zeitpunkt rum, als ich die Feldmarkierungen implementiert habe, muss der Fehler sich eingeschlichen haben.
Leider habe ich eine zeitlang auf einem Windows 7 entwickelt, wo der Fehler nicht auftritt.

Edit: Auch das Einbetten des Hauptpanels (welches das Panel mit der Grafik beinhaltet) in den Frame geschieht nur einmal.
 
Zuletzt bearbeitet:
Ich sehe in deinem Code nichts von einem JFrame! Kann es sein, dass du bei der Erstellung des JFrames den EventDispatch Thread gar nicht verwendest, d.h. ohne: ???
Java:
EventQueue.invokeLater(new Runnable() {
	@Override
	public void run() {
		createFrame();
	}
});
 
Dann kann ich nur weiterraten, was macht
Java:
Game currentgame = GameManager.getInstance().getCurrentGame();
Du machst anscheinend lazy loading, vielleicht macht der GameManager ja was beim ersten getInstance
 
oder auch noch eine Idee..rufst du
Code:
setVisible(true)
auch erst wirklich am Ende, also nachdem alle Componenten hinzugefügt worden sind, auf?
 
Danke für Eure Antworten.


Ich sehe in deinem Code nichts von einem JFrame! Kann es sein, dass du bei der Erstellung des JFrames den EventDispatch Thread gar nicht verwendest, d.h. ohne: ???
Java:
EventQueue.invokeLater(new Runnable() {
	@Override
	public void run() {
		createFrame();
	}
});

Zum Thema Threads bin ich noch überfragt, ich habe selbst noch keine implementiert. Das wäre jetzt der nächste Schritt, vor allem wenn es darum geht, dass ein Mensch gegen einen Computer spielen soll.
Der JFrame kommt folgendermaßen ins Spiel. Die Klasse GUI, stellt quasi die Hauptklasse der View dar und bringt alle Panels zusammen. (Das Mainpanel beinhaltet das Panel mit dem gezeichneten Spielbrett)

Java:
public class GUI extends JFrame {

	private static final long serialVersionUID = 1L;
	String title;

	//Initialisierung des Fensters
	public GUI(String title) {
		super();
		this.setTitle(title);
		this.setPreferredSize(new Dimension(800, 950));
		this.setLocation(500, 25);
		this.initItems();
		this.addWindowListener(new WindowExitListener());
		this.pack();
		this.setVisible(true);
		// this.changeLookAndFeel("com.sun.javax.swing.plaf.metal.MetalLookAndFeel");
	}
	//Initialisierung der Komponenten
	void initItems() {
		this.setLayout(new BorderLayout());
		this.setJMenuBar(new MenuBar());
		JLabel labelUnten = new JLabel("Herzlich Willkommen!");
		labelUnten.setBackground(new Color(176, 196, 222));
		labelUnten.setOpaque(true);
		this.add(new Toolbar(), BorderLayout.NORTH);
		this.add(new MainPanel(), BorderLayout.CENTER);
		this.add(labelUnten, BorderLayout.SOUTH);
		
		
		
	}


oder auch noch eine Idee..rufst du
Code:
setVisible(true)
auch erst wirklich am Ende, also nachdem alle Componenten hinzugefügt worden sind, auf?

Du meinst so, wie ich das oben in der Klasse GUI habe?


Dann kann ich nur weiterraten, was macht
Java:
Game currentgame = GameManager.getInstance().getCurrentGame();
Du machst anscheinend lazy loading, vielleicht macht der GameManager ja was beim ersten getInstance

Die Klasse GameManager soll dem Singleton-Pattern folgen. Hier wird momentan eine Instanz erzeugt, die mir alle Komponenten des Spiels zusammenbringt und mir so den Zugriff auf Objekte innerhalb der anderen Klassen erlaubt. Ich hoffe, man versteht, was ich meine? 🙂

EDIT: Mit der Main in dieser Klasse starte ich momentan auch das Spiel.

Die Gamemanager-Klasse:
Java:
public class GameManager {


	private static GameManager gameManager = null;
	private Game currentGame;

	protected GameManager() {
		currentGame = newHumanGame();
	}

	public static GameManager getInstance() {
		if (gameManager == null) {
			gameManager = new GameManager();
		}
		return gameManager;
	}
	
	public Game getCurrentGame() {
		return currentGame;
	}

	public Game newHumanGame() {
		Player humanA = new Player(true);
		Player humanB = new Player(false);
		currentGame = new Game(humanA, humanB);
		return currentGame;
	}

	public Game newGame(Player playerA, Player playerB) {
		currentGame = new Game(playerA, playerB);
		return currentGame;
	}


	public static void main(String[] args) {
		GameManager.getInstance();


	}

}

Die Klasse Game sieht so aus (auf Attribute gekürzt):
Java:
public class Game {
	
		private Board board;
		private Referee referee;
		private GUI gui;
		private Player[] player;
		private Player currentPlayer;
		private boolean end;
   
		
		public Game(Player playerA, Player playerB) {
			this.board = new Board();
			this.referee = new Referee();
			this.gui = new GUI("Knightsbridge");
			this.player = new Player[2];
			this.player[0] = playerA;
			this.player[1] = playerB;
			this.currentPlayer = playerA;
			this.end = false;
			
		}
 
Zuletzt bearbeitet:
public Game(Player playerA, Player playerB) {
this.board = new Board();
this.referee = new Referee();
--> this.gui = new GUI("Knightsbridge"); <----
this.player = new Player[2];
this.player[0] = playerA;
this.player[1] = playerB;
this.currentPlayer = playerA;
this.end = false;
Du machst da eine neue GUI auf? Das sollte normalerweise nicht so sein. Wenn du schon vom Game aus auf die GUI zugreifen musst (was du anscheinend eh nicht tust) wäre es besser die GUI per Parameter im Konstruktor zu übergeben anstatt eine neue zu machen.
 
Du meinst im Konstruktor für das "Game"? Da wo jetzt die beiden Player drinstehen? Macht das denn effektiv einen Unterschied?
Alle anderen Komponenten erzeuge ich hier ja auch, wo wäre denn dann ein sinnvoller Platz, um die GUI zu erzeugen?
 
Okay, ich habe jetzt den Auslöser des Fehlers etwas eingrenzen können. Wie es aussieht, lösen die Methoden panel.drawPossibleFields(panel.getGraphics()); und panel.markStartField(panel.getGraphics()); im Mouselistener (MousePressed) dieses Flackern aus. Wenn ich die Methoden auskommentiere, flackert nichts. (Wirklich beide Methoden, jede einzeln produziert auch das Flackern)

Allerdings werden diese beiden Methoden auch bei jedem repaint() durchgeführt, was jedoch kein Flackern auslöst.
Mittlerweile denke ich auch, dass das Flackern nicht aus einem ungewollten repaint() bei MousePressed
resultiert. Ich habe ein paar System.out eingebaut und konnte keine Ausgabe bei MousePressed, was auf ein repaint() hindeuten würde, feststellen.

Java:
    @Override
    public void mousePressed(MouseEvent event) {
 
        int xCoord = event.getX();
        int yCoord = event.getY();
//      panel.setDrawDragX(event.getX()); 
//      panel.setDrawDragY(event.getY()); 
        Game currentgame = GameManager.getInstance().getCurrentGame();
        
        if (xCoord > (this.panel.getWidth() / 2 - 280)
                && xCoord < (this.panel.getWidth() / 2 + 280)
                && yCoord > (this.panel.getHeight() / 2 - 280)
                && yCoord < (this.panel.getHeight() / 2 + 280)) {
            
            panel.setIsDragging(true);
            
            int[] pos = this.panel.getPositionOnBoard(xCoord, yCoord);
            // Initialisieren der aktiven Spielfigur
            this.hasPiece = currentgame.getBoard().hasPiece(pos[0], pos[1]);
            if (this.hasPiece){
            panel.initActivepiece(new ActivePiece());
            panel.getActivepiece().setRow(pos[0]);
            panel.getActivepiece().setCol(pos[1]);
            panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0], pos[1]));
            
            panel.getActivepiece().setPossibleFields();

            panel.drawPossibleFields(panel.getGraphics());
            panel.markStartField(panel.getGraphics());

            
            panel.getActivepiece().setPiece(currentgame.getBoard().getFieldPiece(pos[0],pos[1]));
            currentgame.getBoard().setFieldPiece(panel.getActivepiece().getRow(), panel.getActivepiece().getCol(), currentgame.getBoard().getPieceEmpty());
            
            }
        }
        
    }
 
Zuletzt bearbeitet:
Wie es aussieht, lösen die Methoden panel.drawPossibleFields(panel.getGraphics()); und panel.markStartField(panel.getGraphics()); im Mouselistener (MousePressed) dieses Flackern aus.
Genau wegen solchen Sachen sollte man niemals versuchen über getGraphics() einer Komponente an deren Graphics Objekt zu kommen, um damit zu zeichnen.
Gezeichnet wird ausschließlich innerhalb der paint bzw. paintComponent mit dem darin übergebenen Graphics Objekt.
 
Das sehe ich ja ein, aber wie rufe ich dann eine solche Methode außerhalb der eigentlichen Klasse, die die paintComponent()-Methode beinhaltet, auf? Woher kommt dann das benötigte graphics-Object, wenn ich es nicht mit übergebe?
Das mit dem getGraphics benutze ich nur, weil mir das zufällig untergekommen ist. Ich wusste mir nicht anders zu helfen. 🙁
 
Du machst es mit den Figuren und dem Rest auch anders?
In der Methode des MouseListeners wird Information erzeugt, z.B. welches Feld angeklickt wurde und welche Felder potientielle Zielfelder sind. Anschließend wird repaint() aufgerufen.
In der paintComponent werden die zuvor identifizierten Start und Zielfelder entsprechend "markiert"
 
Stimmt, aber bei den Figuren nutze ich die Information, die im Model bereits durch den Listener verändert wurde. Das repaint() führt dann alles nötige aus.
Also muss ich versuchen, das Kennzeichnen der Felder auch vom repaint() abzudecken?
Bei diesem Fall mit den markierten Feldern ist mir kein vernünftiger Weg eingefallen, diese Information anders zu übergeben, als direkt die entsprechende Methode in den Listenern aufzurufen.
Vielleicht steh ich grad auch völlig auf dem Schlauch.
 
Zuletzt bearbeitet:
Thematisch gehört die Information in ein Model. Da für die Spielfiguren ein Model benutzt, kannst Du je einfach dieses erweitern, damit es auch solche Informationen wie Startfeld und Zielfelder speichern kann.
 
Danke für Eure Tipps.

Thematisch gehört die Information in ein Model. Da für die Spielfiguren ein Model benutzt, kannst Du je einfach dieses erweitern, damit es auch solche Informationen wie Startfeld und Zielfelder speichern kann.
In diesem Sinne werden bei mir im model auch die entsprechenden Felder berechnet. Zurückgegeben wird ein Koordinatenarray, das ich dann in der view zum Zeichnen benutze.


Es war jetzt wirklich der von Michael angesprochene Aufruf der Methode getGraphics() das Problem.
Ich rufe die Methoden zum Markieren der Felder jetzt nicht mehr aus dem Mouselistener heraus auf, sondern decke sie mit dem repaint() ab, sodass ich kein graphics-Object von außerhalb an diese Methoden übergeben muss. Daher löst jetzt auch ein MousePressed bei mir einen repaint() aus.
Wenn jemand an der genauen Lösung interessiert ist, kann ich das auch gern noch posten.
Da ich jetzt Stück für Stück weitermachen kann, werde ich sicher noch für die ein oder andere Frage auf dieses Forum zurückkommen.
Danke! 🙂
 
Zuletzt bearbeitet:
Danke für Eure Tipps.


In diesem Sinne werden bei mir im model auch die entsprechenden Felder berechnet. Zurückgegeben wird ein Koordinatenarray, das ich dann in der view zum Zeichnen benutze.


Es war jetzt wirklich der von Michael angesprochene Aufruf der Methode getGraphics() das Problem.
Ich rufe die Methoden zum Markieren der Felder jetzt nicht mehr aus dem Mouselistener heraus auf, sondern decke sie mit dem repaint() ab, sodass ich kein graphics-Object von außerhalb an diese Methoden übergeben muss. Daher löst jetzt auch ein MousePressed bei mir einen repaint() aus.
Wenn jemand an der genauen Lösung interessiert ist, kann ich das auch gern noch posten.
Da ich jetzt Stück für Stück weitermachen kann, werde ich sicher noch für die ein oder andere Frage auf dieses Forum zurückkommen.
Danke! 🙂

EDIT: Als ich die GUI gestern noch in einen eigenen Thread gepackt habe, war auch zu erkennen, dass dieser zweimal gestartet wurde. Geht das überhaupt? Eine Ausgabe der Methode getState() gab zweimal RUNNABLE aus, jetzt nur noch einmal.
Sieht mir doch eher so aus, als wenn das getState() zweimal ausgeführt worden wäre 😉
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben