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. :D

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! :)
 

bERt0r

Top Contributor
Dein code sieht eigentlich ganz ok aus, wie fügst du dein BoardPanel in deinen Frame ein? Ich vermute dass da das Problem liegt.
 

lal000r

Mitglied
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:
 

bERt0r

Top Contributor
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.
 

lal000r

Mitglied
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:

GUI-Programmer

Top Contributor
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();
	}
});
 

bERt0r

Top Contributor
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
 

jgh

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

lal000r

Mitglied
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:

bERt0r

Top Contributor
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.
 

lal000r

Mitglied
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?
 

lal000r

Mitglied
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:

Michael...

Top Contributor
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.
 

lal000r

Mitglied
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. :(
 

Michael...

Top Contributor
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"
 

lal000r

Mitglied
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:

Michael...

Top Contributor
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.
 

lal000r

Mitglied
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:

lal000r

Mitglied
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:
Ähnliche Java Themen
  Titel Forum Antworten Datum
T Flackern trotz DoubleBuffering AWT, Swing, JavaFX & SWT 8
L JButton flackern - Programm hängt sich auf AWT, Swing, JavaFX & SWT 3
G Applet Applet Komponenten flackern AWT, Swing, JavaFX & SWT 10
G Swing Flackern nach Override von paintComponent() AWT, Swing, JavaFX & SWT 3
S Swing Flackern und ausbrechen bei neuzeichnung AWT, Swing, JavaFX & SWT 7
K AWT flackern trotz buffering AWT, Swing, JavaFX & SWT 4
Z Flackern trotz Offscreen Image / Doublebuffer, (+ Frage zu Pixelvergleich) AWT, Swing, JavaFX & SWT 25
J Flackern wie mit BufferedImage beheben AWT, Swing, JavaFX & SWT 4
V Applet JApplet Flackern durch Repaint AWT, Swing, JavaFX & SWT 11
R Flackern beim JPanel-Übermalen AWT, Swing, JavaFX & SWT 9
P SWT SWT flackern beheben AWT, Swing, JavaFX & SWT 9
D Undecorated JFrame ohne Flackern resizen AWT, Swing, JavaFX & SWT 21
K Flackern trotz Double-Buffering AWT, Swing, JavaFX & SWT 10
sylo Flackern des Mauszeigers bei DND AWT, Swing, JavaFX & SWT 4
G ColorReader, bei Fadenkreuz zeichnen mit repaint() flackern AWT, Swing, JavaFX & SWT 19
eQuest Swing Snake repaint() "flackern" AWT, Swing, JavaFX & SWT 13
J Flackern in JEditorPane() AWT, Swing, JavaFX & SWT 14
JRTHEFROG Auflösungsabhängiges Flackern von Bildschirmmasken AWT, Swing, JavaFX & SWT 3
B JFrame flackern durch setSize() AWT, Swing, JavaFX & SWT 8
N Flackern beim neuzeichnen von JPanel AWT, Swing, JavaFX & SWT 19
S Falsche Position, Elemente erscheinen nicht, Flackern AWT, Swing, JavaFX & SWT 6
S animation Flackern trotz doppelpufferung wieso? AWT, Swing, JavaFX & SWT 2
U Flackern verhindern AWT, Swing, JavaFX & SWT 5
J Flackern beim ersten laden von JPanel AWT, Swing, JavaFX & SWT 4
T Labels verschieben / Flackern AWT, Swing, JavaFX & SWT 2
Fragerjava Frame inhalt komplett löschen AWT, Swing, JavaFX & SWT 4
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
Kotelettklopfer Frame ändert Farbe nicht AWT, Swing, JavaFX & SWT 12
P Swing Zufallsbilder auf Frame ausgeben AWT, Swing, JavaFX & SWT 1
D AWT Wie kann ich ein Frame von einem anderen aus beeinflussen? AWT, Swing, JavaFX & SWT 7
R 2D-Grafik Massive Frame Drops beim Benutzen von AffineTransformOp AWT, Swing, JavaFX & SWT 2
C Swing F5 Taste neu laden auf ganzen Frame AWT, Swing, JavaFX & SWT 9
J Genutzte Methoden in einen Frame einbauen AWT, Swing, JavaFX & SWT 21
H Swing Frame an andere Klassen weitergeben AWT, Swing, JavaFX & SWT 4
olfibits Swing JavaFX-Frame in JDesktopPane darstellen? AWT, Swing, JavaFX & SWT 2
F Swing Frame nach vorne holen AWT, Swing, JavaFX & SWT 2
J Panel auf Frame positionieren AWT, Swing, JavaFX & SWT 9
K Frame aus anderer Klasse schließen AWT, Swing, JavaFX & SWT 3
F AWT mehrere Panels in einem Frame AWT, Swing, JavaFX & SWT 17
S Tastatur frame nur nur 1 mal öffnen AWT, Swing, JavaFX & SWT 1
T Swing Java-Frame bei Programmstart NICHT im Vordergrund öffnen AWT, Swing, JavaFX & SWT 2
A Programm nun in ein Frame basteln AWT, Swing, JavaFX & SWT 1
T Frame öffnet nicht AWT, Swing, JavaFX & SWT 1
A Swing GUI - Button soll Frame verändern AWT, Swing, JavaFX & SWT 4
Java_RY AWT Frame in eine eigene klasse auslagern und aufrufen AWT, Swing, JavaFX & SWT 6
S mit keylistener frame schliessen AWT, Swing, JavaFX & SWT 8
Thallius Wer oder was bestimmt welches Frame toFront kommt wenn ein anderes geschlossen wird? AWT, Swing, JavaFX & SWT 8
Z Swing Frame wird geöffnet, aber ist ohne Inhalt AWT, Swing, JavaFX & SWT 0
J Panel auf Frame löschen und neues Panel Hinzufügen AWT, Swing, JavaFX & SWT 4
D Frame beim starten eines anderen Frames schließen AWT, Swing, JavaFX & SWT 2
S NetBeans, Panel in Frame einfügen AWT, Swing, JavaFX & SWT 3
M Internal Frame in den vordergrund AWT, Swing, JavaFX & SWT 4
Tausendsassa Frame öffnet aber zeigt keinen Inhalt... AWT, Swing, JavaFX & SWT 10
Tom299 JavaFX Ähnliche Komponente wie der VB6 Frame? AWT, Swing, JavaFX & SWT 2
L Swing Frame in Thread wird nicht gezeichnet AWT, Swing, JavaFX & SWT 2
K Swing JScrollPane - JScrollBar anzeigen, wenn Frame verkleinert wird AWT, Swing, JavaFX & SWT 3
D Buttons erscheinen nicht auf Frame AWT, Swing, JavaFX & SWT 2
M Swing Probleme mit Frame.pack() AWT, Swing, JavaFX & SWT 1
B Frame hängt sich auf trotz invokeLater AWT, Swing, JavaFX & SWT 1
D jButton Problem, ein Rieser Button bedeckt das ganze frame AWT, Swing, JavaFX & SWT 1
M JavaFX wie kann mann sein frame mit einem Icon fersehen? AWT, Swing, JavaFX & SWT 2
Z Canvas in Frame einfügen. Problem mit 4-Gewinnt AWT, Swing, JavaFX & SWT 1
P Frame friert ein AWT, Swing, JavaFX & SWT 6
Z Frame mit Rechteck! AWT, Swing, JavaFX & SWT 16
Messoras JWindow/Frame durch das man durchklicken kann AWT, Swing, JavaFX & SWT 5
M Swing "Frame.setResizable(false);" verschiebt Content? AWT, Swing, JavaFX & SWT 9
X Swing 1 JButton bedeckt meine ganze Frame aber Warum? AWT, Swing, JavaFX & SWT 2
J JTable aktuallisieren über anderen Frame AWT, Swing, JavaFX & SWT 6
J JTable Zeile anklicken und neues Frame öffnen AWT, Swing, JavaFX & SWT 4
S Quadrat auf Frame zeichnen AWT, Swing, JavaFX & SWT 2
B JFrame immer an gleicher stelle auf anderem Frame AWT, Swing, JavaFX & SWT 5
F JAVA-EDITOR: Panel in Frame aufnehmen AWT, Swing, JavaFX & SWT 3
B Swing JMenuBar unten in der Frame setzen? AWT, Swing, JavaFX & SWT 15
U Frame zeigt keine Komponenten AWT, Swing, JavaFX & SWT 7
L JButton im Frame fest verankern AWT, Swing, JavaFX & SWT 0
D Buttons erscheinen nicht auf dem zweiten Frame AWT, Swing, JavaFX & SWT 4
X Swing Größe eines Fensters JFrame / Frame AWT, Swing, JavaFX & SWT 5
BRoll Frame- Video einbinden machbar? AWT, Swing, JavaFX & SWT 6
Kandum obj_JMenu.addMenuListener - variable Anzahl an JMenus / menulistenern & frame.setTitle() dynamisch AWT, Swing, JavaFX & SWT 7
B Frame always on top nur auf anderem Frame AWT, Swing, JavaFX & SWT 9
S Aufteilung von JPanels in einem Frame AWT, Swing, JavaFX & SWT 13
K Options-Frame integrieren (zum zuschalten und wegschalten wie geht man da ran? AWT, Swing, JavaFX & SWT 7
J Frame mit Button erstellen - Warum ist es nötig, Frame über Unterklasse zu erstellen? (Reg Listener) AWT, Swing, JavaFX & SWT 2
N Swing Endlosschleife blockt Frame AWT, Swing, JavaFX & SWT 11
B Swing JDialog modal, aber trotzdem Frame auswählbar AWT, Swing, JavaFX & SWT 2
N Swing Frame ungewollt transparent! AWT, Swing, JavaFX & SWT 2
J Kleines Anzeige Problem(nur blanker Frame) AWT, Swing, JavaFX & SWT 22
D Neues Frame öffnen - und dazu altes schließen AWT, Swing, JavaFX & SWT 5
Daniel_L Drop von Dateien auf Frame - welche Drop-Location? AWT, Swing, JavaFX & SWT 2
J JMenuBar ist geaddet, aber nicht im Frame. Wo ist der Fehler? (inkl. Code) AWT, Swing, JavaFX & SWT 2
C LookAndFeel Frame updated nicht vollständig AWT, Swing, JavaFX & SWT 9
K 3D-Grafik Canvas ist ein eigener Frame?! AWT, Swing, JavaFX & SWT 13
L Jbutton + jcombobox mit vorhandenen frame verknüfen AWT, Swing, JavaFX & SWT 8
J 2 Bereiche im Frame komplett nutzen - Welchen Layoutmanager? AWT, Swing, JavaFX & SWT 3
Z Swing JTextfield auf Frame AWT, Swing, JavaFX & SWT 13
N Swing Frame mit GlassPane und Popup AWT, Swing, JavaFX & SWT 5
L Frame Schließen und neustarten AWT, Swing, JavaFX & SWT 4
L Mehre Panels einen Frame zuweisen AWT, Swing, JavaFX & SWT 11
P Frame "always on top" und welche GUI? AWT, Swing, JavaFX & SWT 5
Furtano AWT mehrere Bilder in einen Frame zeichnen + Layout Manager AWT, Swing, JavaFX & SWT 10

Ähnliche Java Themen

Neue Themen


Oben