Timer w klasie dziedziczącej po JPanel

0

Witam
Piszę grę kółko i krzyżyk, a w zasadzie już prawie skończyłem.
Mam 2 klasy dziedziczące JPanel:
RysowanieGrafiki - rysuję tło, obrazek, który pokazuje aktualnego gracza itp.
RysowaniePlanszy - w drugiej planszę gry oraz X i O na niej.

Problem polega na tym, że pole z planszą strasznie migocze. Domyślam się, że spowodowane jest to tym, że w metodach paintComponent() (w obu klasach) wywołuję repaint() (wiem, nie powinno się tak robić) i gra nie wyrabia z rysowaniem.

Chcę zastosować TimerTask, jednak klasy rysujące mogą dziedziczyć tylko po jednej klasie, z czego wynika, że nie mogą dziedziczyć po TimerTask, ponieważ dziedziczą już po JPanel.

PS
Czytałem gdzieś, że JPanel ma automatycznie włączone podwójne buforowanie, to prawda?

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;


public class RysowaniePlanszy extends JPanel implements MouseListener
{
	public static Integer pozX = new Integer(0);
	public static Integer pozY = new Integer(0);
	
	public static Image[] obrazki = new Image[6]; 

	RysowaniePlanszy() 
	{
        super();
		addMouseListener(this);

		try 
        {
        	for(int i=1; i<=5; i++)
            obrazki[i] = ImageIO.read(new File("src/img/" + i + ".png"));
		} 
        catch (IOException e) {e.printStackTrace();}
		
	}
	
	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) 
	{
			pozX = Math.round(e.getX()/100);
			pozY = Math.round(e.getY()/100);	
			Silnik.klikniecie = true;
			System.out.println(pozX + "  " + pozY);
	}
	
	
	
	protected void paintComponent(Graphics g) 
	{
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;
		
		for(int j=0; j<Silnik.plansza.length; j++)
		{
			for(int i=0; i<Silnik.plansza[0].length; i++)
			{		
				g2d.drawRect(100*j, 100*i, 100, 100);
					switch(Silnik.plansza[j][i])
					{
						case 1:
						{
							g2d.drawImage(obrazki[1], 100*j, 100*i, this);
							break;
						}
						case 2:
						{
							g2d.drawImage(obrazki[2], 100*j, 100*i, this);
							break;
						}
					}
			}
		}
		repaint();
	}
}
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JPanel;


public class RysowanieGrafiki extends JPanel 
{
 	RysowanieGrafiki() 
	{
		super();
	}	

 	public void update( Graphics g )
    {
        paintComponent(g);
    }
 	
	protected void paintComponent(Graphics g) 
	{
		super.paintComponent(g);
		Graphics2D G2d = (Graphics2D) g;
	
			G2d.drawImage(RysowaniePlanszy.obrazki[3], 0, 0, this);

			if(Silnik.aktualnyGracz == 'X')
			{
				G2d.drawImage(RysowaniePlanszy.obrazki[4], -80, 300, this);
			}
			if(Silnik.aktualnyGracz == 'O')
			{
				G2d.drawImage(RysowaniePlanszy.obrazki[5], -80, 300, this);
			}
			repaint();
	}
}

0

Po jakiego grzyba dziedziczenie po TimerTask? Czy Twoje klasy rysujące zadaniem timera?
Wywal te repainty z paintComponent bo Swing i tak olewa te wywołania jeżeli są nadmiarowe. Przenieś je do metody wywoływanej jako zadanie timera, a wcześniej w klasach rysujących wywołaj setIgnoreRepaint(true), żeby odmalowywanie było wymuszone tylko przez timera, a nie przez inne zdarzenia. A tak w ogóle to bardzo źle ponazywałeś te klasy. RysowaniePlanszy powinno nazywać się Plansza bo jest to JPanel i RysowanieGrafiki powinno nazywać się - w sumie to nie wiem jak bo ty dwa panele nakładasz na siebie.
Migotanie nie wynika z wrzucenie repaintów tam gdzie ich w ogóle nie powinno być, lecz z powodu wywoływania przez Ciebie metody super.paintComponent(), której pierwszym zadaniem jest wymazanie całej powierzchni komponentu związanego z panelem kolorem tła. Robi to naprzemiennie z malowaniem obrazków, więc masz naprzemiennie rysowanie obrazka i mazanie go w losowych odstępach czasu.

Jeżeli chcesz sensownie się pobawić Swingiem w celu zrobienia jakiejś prostej gry, to zacznij najpierw od zrozumienia kilku prostych przykładów z tutoriala i ewentualnie rozszerzenie ich do swoich potrzeb jako gier. Szybciej się nauczysz niż błądząc jak latynoski partyzant po dżungli. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1