Widoczność obiektów w programie

0

Witam! Tak wygląda mój program:

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

/************************************** FOOTBALLER ***************************************************/
class Footballer implements Runnable
	{
		int x;
		int y;
		String name;
		
		Color footballerColor;
		
		public Footballer(int posX, int posY, String na, Color col)
		{
			x = posX;
			y = posY;
			name = na;
			footballerColor = col;
		}
		
		public void moveF(int dX, int dY)		// argumenty mogą być tylko -1, 0 lub 1
		{
			x += dX;
			y += dY;
		}
		
		public void paint(Graphics g)
		{
			g.setColor(footballerColor);
			g.fillRect(x, y, 10, 10);
		}
		
		public void setPosition(int posX, int posY)
		{
			x = posX;
			y = posY;
		}
		
		public void run()
		{
			
		}
	}

/************************************** BALL ****************************************************/
class Ball implements Runnable
{
	int x;
	int y;
	Color ballColor;
	
	public Ball(int posX, int posY, Color col)
	{
		x = posX;
		y = posY;
		ballColor = col;
	}
	
	public void moveF(int dX, int dY)	
	{
		x += dX;
		y += dY;
	}
	
	public void paint(Graphics g)
	{
		g.setColor(ballColor);
		g.fillOval(x, y, 7, 7);
	}
	
	public void setPosition(int posX, int posY)
	{
		x = posX;
		y = posY;
	}
	
	public void run()
	{
	
	}
}

/************************************** PITCH ***************************************************/
class PitchPanel extends JPanel implements KeyListener
{		
		public final Footballer player1 = new Footballer(100,100,"Boniek",new Color(140,180,170));  
		public final Footballer player2 = new Footballer(500,100,"Komputer",new Color(220,100,200));
		public final Ball ball = new Ball(400,400,new Color(255,250,250));				
			
		public PitchPanel()
		{
			this.setFocusable(true);
			this.addKeyListener(this);
		}	
							
		public void paint(Graphics g)
		{					
			Color GrassColor = new Color(45,123,27);		// kolor trawy
			Color LineColor = new Color(250,250,250);		// kolor linii
			
			g.setColor(GrassColor);							// trawa
			g.fillRect(20,80,745,500);						
			g.setColor(LineColor);							// linie wyznaczające boisko
			g.drawLine(40,90,745,90);						
			g.drawLine(745,90,745,570);
			g.drawLine(40,90,40,570);
			g.drawLine(40,570,745,570);
			g.drawRect(30,300,10,60);						// bramki
			g.drawRect(745,300,10,60);
			
			//Stworzenie gracza - trzeba będzie zautomatyzować	
			player1.run();	
			player1.paint(g);
			player2.run();
			player2.paint(g);
			ball.run();
			ball.paint(g);		
		}
		
		// Obsługa klawiszy
		public void keyTyped(KeyEvent e)
		{

		}
		
		public void keyPressed(KeyEvent e)
		{
			if(e.getKeyCode() == KeyEvent.VK_LEFT)
			{
				player1.moveF(-1,0);
				repaint();
				System.out.println(e);
			}		
		}
		
		public void keyReleased(KeyEvent e)
		{}
		
		// Funkcje "z zewnątrz"
		public void gameWithComputerStart()
		{
			player1.setPosition(400,400);
			player2.setPosition(450,400);
			ball.setPosition(425,400);
			repaint();
		}		
}

/************************************** FOOTBALL ***************************************************/
public class Football extends JFrame implements ActionListener
{
		// deklaracja referencji do elementów menu
		JMenuBar jmb;
		JMenu mGame;
		JMenuItem miNewGame;
		JMenuItem miOptions;
		JMenuItem miExit;
		JMenu mInfo;
		JMenuItem miHelp;
		JMenuItem miAbout;	
			
		newGameDialog ngDialog;
		public PitchPanel pitch;
				
	public static void main(String[] args) 
	{
		Football okno = new Football("Football");
		okno.init();
	}
	
	Football(String tekst)
	{
		super(tekst);
		ngDialog = new newGameDialog();
	}
	
	void init()
	{
		// funkcje wywoływane na rzecz okna
		setSize(800,650);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setResizable(false);
		
		// Layout
		Container cp = getContentPane();
		cp.setLayout(new BorderLayout());
		
		// Menu górne
		jmb = new JMenuBar();
		//
		mGame = new JMenu("Game");
		miNewGame = new JMenuItem("New game");
		miOptions = new JMenuItem("Options");
		miExit = new JMenuItem("Exit");
		//
		mInfo = new JMenu("Info");
		miHelp = new JMenuItem("Help");
		miAbout = new JMenuItem("About Program");		
		
		// ułożenie menu
		mGame.add(miNewGame);
		mGame.add(miOptions);
		mGame.add(miExit);
		mInfo.add(miHelp);
		mInfo.add(miAbout);
		jmb.add(mGame);
		jmb.add(mInfo);
		cp.add(jmb, BorderLayout.NORTH);		
		
		// stworzenie i ułożenie pozostałych elementów programu
		pitch = new PitchPanel();
		add(pitch);
		
		// Dodanie listenera do menu
		miNewGame.addActionListener(this);

		// pokazanie okna
		setVisible(true);
	}
	
	// nasłuchiwanie na kliknięcia w menu
	public void actionPerformed(ActionEvent zdarzenie)
	{
		Object zrodlo = zdarzenie.getSource();
		if(zrodlo == miNewGame)
		{
			ngDialog.setVisible(true);
		}
	}
}

// ***************************** NEW GAME DIALOG **********************************************/
class newGameDialog extends JDialog implements ActionListener
{
	JLabel labelChooseTypeOfGame;
	JComboBox opponentsCbox;
	JScrollPane sp;
	JButton confirmButton;
	
	public newGameDialog()
	{
		this.setSize(200,150);
		this.setResizable(false);
		this.init();
	}
	
	public void init()
	{	
		String[] kindsOfGames = new String[2];
		kindsOfGames[0] = "Gra z komputerem";
		kindsOfGames[1] = "Gra on-line";
		labelChooseTypeOfGame = new JLabel("Wybierz rodzaj gry");
		opponentsCbox = new JComboBox(kindsOfGames);
		confirmButton = new JButton("Start");
		confirmButton.addActionListener(this);
		
		Container cp = getContentPane();
		cp.setLayout(new FlowLayout());
		cp.add(labelChooseTypeOfGame);
		sp = new JScrollPane(opponentsCbox);
		cp.add(sp);
		cp.add(confirmButton);
		cp.setVisible(true);
	}
	
	public void actionPerformed(ActionEvent zdarzenie)
	{
		Object zrodlo = zdarzenie.getSource();
		if(zrodlo == confirmButton)
		{
			if(opponentsCbox.getSelectedIndex() == 0)		// wybranie gry z komputerem
			{
				pitch.gameWithComputerStart();   // <-------- !! TUTAJ CHCĘ WYWOŁAĆ FUNKCJĘ NA 
												 //RZECZ OBIEKTU KLASY PITCHPANEL !!
			}
			else if(opponentsCbox.getSelectedIndex() == 1)	// wybranie gry on-line
			{
				
			}
			this.setVisible(false);			
		}
	}
}

Problem leży w tym, że chcę z obiektu ngDialog (klasa newGameDialog) wywołać funkcję gameWithComputerStart() na rzecz obiektu pitch (klasy PitchPanel). Obiekt pitch jest tworzony w głównej klasie programu, a referencja do niego ma dostęp public.

To dopiero moje pierwsze kroki w JAVIE i za Chiny nie mogę zrozumieć dlaczego referencja pitch nie jest widoczna we wszystkich klasach programu, mimo że poprzedziłem ją słowem kluczowym public w momencie deklaracji (deklaracja jest w głównej klasie programu).

Bardzo proszę o informację co muszę zrobić żeby referencja pitch była widoczna we wszystkich klasach w tym pliku, tak abym mógł wywołać potrzebną funkcję w następujący sposób: pitch.gameWithComputerStart(); (końcówka programu).

0

Musisz do klasy newGameDialog przekazać referencje do obiektu klasy PitchPanel

        public static void main(String[] args)
        {
                Football okno = new Football("Football");
                okno.init();
                ngDialog = new newGameDialog(pitch);
        }
       
        Football(String tekst)
        {
                super(tekst);
        }
.............
        JLabel labelChooseTypeOfGame;
        JComboBox opponentsCbox;
        JScrollPane sp;
        JButton confirmButton;
        PitchPanel pitch;
       
        public newGameDialog(PitchPanel pitch)
        {
                this.setSize(200,150);
                this.setResizable(false);
                this.init();
                this.pitch=pitch;
        }
0

Zrobiłem tak jak napisałeś, z jedną różnicą - zamiast:

 
public static void main(String[] args)
        {
                Football okno = new Football("Football");
                okno.init();
                ngDialog = new newGameDialog(pitch);
        }
       
        Football(String tekst)
        {
                super(tekst);
        }

Zrobiłem tak:

	public static void main(String[] args) 
	{
		Football okno = new Football("Football");
		okno.init();
	}
	
	Football(String tekst)
	{
		super(tekst);
		ngDialog = new newGameDialog(pitch);
	}

Ponieważ kompilator rzucał się, że niestatyczna zmienna ngDialog nie może być "referenced" ze statycznego kontekstu, dlatego przypisanie do niej przerzuciłem do konstruktora Football, tak jak widać powyżej.

Problem z zakresem widoczności referencji jest już rozwiązany - dzięki za pomoc!

Niestety przy okazji wypłynął kolejny problem. Oto fragment programu, którego dotyczy:

	public void actionPerformed(ActionEvent zdarzenie)
	{
		Object zrodlo = zdarzenie.getSource();
		if(zrodlo == confirmButton)			// działa
		{	
			int wybor = opponentsCbox.getSelectedIndex();		// działa
			
			if(wybor == 0)		// wybranie gry z komputerem	// działa
			{
				labelChooseTypeOfGame.setText("0");				// pomocniczo - działa
				this.setVisible(false);							// działa
				pitch.gameWithComputerStart();					// NIE DZIAŁA - EKRAN SIĘ NIE PRZERYSOWYWUJE	
			}
			else if(wybor == 1)	// wybranie gry on-line			// działa
			{	
				labelChooseTypeOfGame.setText("1");				// pomocniczo - działa
			}	
		}
	}

Generalnie cała funkcja działa, za wyjątkiem kluczowego momentu, w którym korzystam z wspomnianej referencji pitch, żeby na jej rzecz uruchomić funkcję gameWithComputerStart(). Funkcja ta ma ustawić nowe położenie zawodników oraz piłki, oraz wyrysować je na ekranie. Niestety nic się nie dzieje. Główkuję nad tym od 80 minut i nie mam zielonego pojęcia w czym rzecz. Jeśli ktoś zna rozwiązanie problemu, to proszę o pomoc.

0

A nie pojawia się wyjatek NullPointerException? Ja celowo zmieniłem kolejność:

        public static void main(String[] args)
        {
                Football okno = new Football("Football");
                okno.init(); // dopiero tu jest tworzonyc pitch
        }
       
        Football(String tekst)
        {
                super(tekst);
                ngDialog = new newGameDialog(pitch); // zatem w tym miejscu pitch==null
        }
0

Faktycznie - oczywiście, że masz rację - był wyjątek NullPointerException. Przepraszam, jakoś przeoczyłem to co JRE wypisuje na konsoli.

Wrzuciłem linijkę

ngDialog = new newGameDialog(pitch);

do init-a i już wszystko działa.

Dzięki za pomoc! :)

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