Witam. Próbuję znaleźć powód dla którego dostaje losowo NullPointerExcetion w prostym programie. Program ma symulować dwa różne kolory płytek ganiające się za sobą. Jak na razie jest tylko jeden kolor i nie robi nic poza pojawieniem się w losowym miejscu na planszy. Wszystko fajnie, działa ale z jakiegoś powodu wyskakuje ten chory nullpointer. Nie ma zasady, raz wyrzuci raz nie. Zawsze natomiast po utworzeniu wszystkich 6 wątków. Jedyne podejrzenie jakie mam to to, że może problem polega na tym, że szybciej wątek próbuje pokolorować JPanel , niż go stworzyć. Ale jako że dzieje się to w EventQueue to raczej niemożliwe. Ktoś coś ?
MainFrame.java
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame{
JButton Close;
JButton New;
JButton Initialize;
JButton Stop;
JButton Start;
JPanel ButtonPanel;
JPanel ViewPanel;
JPanel RightMargin;
JPanel LeftMargin;
JPanel BottomMargin;
JPanel[][] PanelsTab;
public MainFrame(int MapSizeX, int MapSizeY) {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocation(500, 200);
setSize(800, 800);
setLayout(new BorderLayout());
Close = new JButton("Zamknij");
New = new JButton("Czysc");
Initialize = new JButton("Inicjuj");
Start = new JButton("Start");
Stop = new JButton("Stop");
ButtonPanel = new JPanel(new FlowLayout());
ViewPanel = new JPanel(new GridLayout(MapSizeX, MapSizeY, 2, 2));
ButtonPanel.add(Initialize);
ButtonPanel.add(Start);
ButtonPanel.add(Stop);
ButtonPanel.add(New);
ButtonPanel.add(Close);
PanelsTab = new JPanel[MapSizeX][MapSizeY];
RightMargin = new JPanel();
LeftMargin = new JPanel();
BottomMargin = new JPanel();
for(int i = 0; i < MapSizeX; i++ ) {
for(int j = 0; j < MapSizeY; j++) {
PanelsTab[i][j] = new JPanel();
PanelsTab[i][j].setBackground(Color.WHITE);
ViewPanel.add(PanelsTab[i][j]);
}
}
add(RightMargin, BorderLayout.LINE_END);
add(LeftMargin, BorderLayout.LINE_START);
add(BottomMargin, BorderLayout.PAGE_END);
add(ViewPanel, BorderLayout.CENTER);
add(ButtonPanel, BorderLayout.NORTH);
Close.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
}
});
setVisible(true);
}
}
GUI.java
import java.awt.Color;
import java.awt.EventQueue;
public class GUI implements Runnable{
private int MapSizeX;
private int MapSizeY;
private static MainFrame MainFrame1;
public GUI(int x, int y) {
this.MapSizeX = x;
this.MapSizeY = y;
}
public void run() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MainFrame1 = new MainFrame(MapSizeX, MapSizeY);
}
});
}
public static void InsertRabbit(int x, int y) {
MainFrame1.PanelsTab[x][y].setBackground(Color.BLUE);
}
public static void InsertWolf(int x, int y) {
MainFrame1.PanelsTab[x][y].setBackground(Color.RED);
}
public static void Clear(int x, int y) {
MainFrame1.PanelsTab[x][y].setBackground(Color.WHITE);
}
}
Rabbit.java
import java.awt.EventQueue;
public class Rabbit implements Runnable{
private int posX;
private int posY;
private boolean isAlive;
private int RabbitNumber;
public Rabbit(int number) {
this.isAlive = true;
this.RabbitNumber = number;
int helpX = Simulate.Generator.nextInt(Simulate.MapSizeX);
int helpY = Simulate.Generator.nextInt(Simulate.MapSizeY);
while(Simulate.Mapa.CheckContent(helpX, helpY) != "Clear") {
helpX = Simulate.Generator.nextInt(Simulate.MapSizeX);
helpY = Simulate.Generator.nextInt(Simulate.MapSizeY);
}
this.posX = helpX;
this.posY = helpY;
Simulate.Mapa.InstertRabbit(this.posX, this.posY);
System.out.println("Rabbit number " + RabbitNumber + " has been born on " + (this.posX) + " " + (this.posY) + "!");
EventQueue.invokeLater(new Runnable()
{
public void run() {
GUI.InsertRabbit(posX, posY);
}
});
}
private synchronized void Move() {
while(isAlive) {
try{
System.out.println("Rabbit number " + this.RabbitNumber + " is moving!");
wait(5000);
}catch(InterruptedException e) {
System.out.println("Ohh noes, rabbit number " + this.RabbitNumber + " is dead but not in natural way!");
}
}
}
public void run(){
//Move();
}
}
Wolf.java
public class Wolf implements Runnable{
public void run(){
}
}
Simulate.java
import java.util.Random;
public class Simulate {
public static int WolfsAmount = 0;
public static int RabbitsAmount = 0;
public static int MapSizeX;
public static int MapSizeY;
public static Map Mapa;
public static Random Generator;
public static Thread[] RabbitsTab;
public static Thread[] WolfsTab;
public static void main(String[] args) {
if(args.length < 4) {
System.out.println("Za malo argumentow!");
return;
}
try{
MapSizeX = Integer.parseInt(args[0]);
MapSizeY = Integer.parseInt(args[1]);
WolfsAmount = Integer.parseInt(args[2]);
RabbitsAmount = Integer.parseInt(args[3]);
if(MapSizeY < 2 || MapSizeX < 2 ||WolfsAmount < 1 || RabbitsAmount < 1) {
System.out.println("Nieprawidlowe dane startowe!");
return;
}
Generator = new Random();
Mapa = new Map(MapSizeX, MapSizeY);
GUI GuiT = new GUI(MapSizeX, MapSizeY);
Thread GUIThread = new Thread(GuiT);
GUIThread.start();
RabbitsTab = new Thread[RabbitsAmount];
WolfsTab = new Thread[WolfsAmount];
for(int i = 0; i < RabbitsAmount; i++) {
RabbitsTab[i] = new Thread(new Rabbit(i + 1));
RabbitsTab[i].start();
}
}catch(NumberFormatException e){
System.out.println("Dane startowe nie sa liczbami!");
}
}
}
Map.java
public class Map {
private String[][] Content;
private int height;
private int width;
public Map(int x, int y){
this.height = x;
this.width = y;
this.Content = new String[x][y];
for(int i = 0; i < x; i++) {
for(int j = 0; j < y; j++) {
this.Content[i][j] = "Clear";
}
}
}
public void Clear(int x, int y) throws Exception{
if(x < 0 || x > this.height - 1 || y < 0 || y > this.width -1) {
throw new Exception("Out of range!");
}
this.Content[x][y] = "Clear";
}
public void ClearAll() {
for(int i = 0; i < this.height; i++) {
for(int j = 0; j < this.width; j++) {
this.Content[i][j] = "Clear";
}
}
}
public void InsertWolf(int x, int y) {
this.Content[x][y] = "Wolf";
}
public void InstertRabbit(int x, int y) {
this.Content[x][y] = "Rabbit";
}
public String CheckContent(int x, int y) {
return this.Content[x][y];
}
}