Swing, JPanel, paintcomponent, jak przekazać argument

0

Od weekendu przysiadłem sobie do nauki Java i na rozruch robię sobie okienkową gierkę/strzelankę z próbą wykorzystania MVC i Swing.

Jako sceny na której co każdy tick timera rysowane są obiekty, używam elementu JPanel.

Tutaj mam takie pytanie:
Mam klasę odpowiedzialną za właśnie tę scenę i rysowanie po niej, co oczywiste extends JPanel i** override paintcomponent**, i chciałbym, żeby robiła właśnie tylko to, rysowała po scenie. W obecnej postaci, z tego powodu, że żeby móc ją nadpisać, metoda paintcomponent przyjmuje standardowo tylko jeden zdefiniowany rodzaj argumentu, a co za tym idzie, nie mogę przekazać sobie nowego obiektu do narysowania z poziomu kontrolera, bezpośrednio do tej metody. Muszę zrobić to tak, że mam kopię zmiennych w klasie JPanel.
Chodzi mi o to, że teraz moja klasa JPanel przechowuje kopie zmiennych zawierające w sobie informacje o obiektach do narysowania, i te zmienne są aktualizowane co tick timera. Co za tym idzie, muszę z góry zdefiniować wewnątrz paintcomponent co i jak będzie narysowane. Chciałbym dowiedzieć się, czy da się to ominąć i bezpośrednio przekazać obiekty do tej metody, tak by dalej nadpisywała ona metodę bazową i była wywoływana razem z repaint().
Core gierki jest już zrobione i powinienem zaimplementować resztę moich pomysłów. Wszystko działa i teraz, ale nie chciałbym przetrzymywać kopii tych zmiennych, bo teraz jest to ścieżka Model->Controller->kopie zmiennych->View aktualizacja kopii zmiennych-> rysowanie, a chciałbym Model->Controller i wywołanie metody z View, i przekazanie zmiennych-> View i rysowanie;

Poglądowo przykład kodu:

 
public class GameSceneView extends JPanel
{
	static private ArrayList<Enemy> listOfEnemyShips;

	public GameSceneView(int width, int height) 
	{
		setPreferredSize(new Dimension(width, height));

		listOfEnemyShips = new ArrayList<Enemy>();
	}

	//metoda do nadpisania listy zawierającej obiekty do narysowania, wywoływana z kontrolera co każdy tick Timera
	public void updateListOfEnemyShips(ArrayList<Enemy> listOfEnemyShips)
	{
		GameSceneView.listOfEnemyShips = listOfEnemyShips;
	}

	//nadpisany paintComponent, metoda repaint() wywołana w kontrolerze co każdy tick Timera
	@Override public void paintComponent(Graphics g)
	{		
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;

		//rysowanie wszystkich obiektów z listy
		for (Enemy enemy : listOfEnemyShips)
		{
			g2.drawImage(enemy.getImageOfEnemy(), enemy.getLocation().x, enemy.getLocation().y,
					enemy.getSize().width, enemy.getSize().height, null);
		}
	}
}

A chciałbym coś takiego:

 
public class GameSceneView extends JPanel
{
	public GameSceneView(int width, int height) 
	{
		setPreferredSize(new Dimension(width, height));
	}

	//nadpisany paintComponent, metoda repaint() wywołana w kontrolerze co każdy tick Timera
	@Override public void paintComponent(Graphics g, ArrayList<T> listOfObjects)
	{		
		//wykonuje magię voodo, czary mary i rysuje obiekty z przekazanej listy
	}
}

Następną kwestią o którą chciałbym się zapytać, to czy da się przekazać taką listę do metody bez definiowania typu zmiennych ( tak, bym mógł przekazać do funkcji listę ze zmiennymi Enemy oraz listę ze zmiennymi Bullet). Mam listy ze zmiennymi do narysowania, dziedziczącymi po obiekcie Rectangle, więc wszystkie mają standardowo dane o ich wielkości i położeniu. Chyba, że powinienem zabrać się do tego od kombinowania z metodą paintComponent(), albo utworzyć dodatkową klasę która będzie zajmować się tylko tym.
Nigdy czegoś takiego nie robiłem ani nie zastanawiałem się, czy można, więc pytam. Jeśli tak, to o czym poczytać.
Jeśli pytania durne, to przypominam, ogarniam to od weekendu.

0
  1. Muszę zrobić to tak, że mam kopię zmiennych w klasie JPanel. -> Nie ma tu żadnej kopii, ot po prostu masz tutaj tą referencje. Co więcej to jest pewnie stała referencja (tzn listę alokujesz raz) więc w ogóle nie musisz nic przekazywać. Zmiana oryginalnej listy w kontrolerze będzie widoczna też tutaj. Szukasz problemów tam gdzie ich po prostu nie ma.
  2. Musiałbyś mieć klasę bazową dla wszystkich obiektów które chcesz rysować, moze to być choćby ten Rectangle, to bez różnicy i wtedy mozesz wszystko trzymać w liście jako rectangle.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.