JPanel + MouseListener

FaJo

Mitglied
Hallo zusammen,

habe folgendes Problem, möchte zu einem JPanel einen Mouselistener hinzufügen.
Der Listener soll die Koordinate auslesen und an dem Punkt eine '1' setzen(Game of Life).
Habe ich soweit mal Ausporbiert jedoch schmeißt er mir jetzt nen Fehler raus:

Fehler:

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 30
at Game.GameOfLifeGUI$1.mouseClicked(GameOfLifeGUI.java:55)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Hier der zugehörige Code:

-GameOfLifeGui
Java:
package Game;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;

@SuppressWarnings("serial")
public class GameOfLifeGUI extends JFrame {

	private final JLabel m_oHeading;
	private final Box m_oMainbox;
	private final JButton m_oStart;
	private final JTextArea m_oBakterien;
	private final JLifePanel m_oScroll;
	
	MouseListener mouse = new MouseListener() {

		@Override
		public void mouseReleased(MouseEvent e) {
		}

		@Override
		public void mousePressed(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub

		}

		@Override
		public void mouseClicked(MouseEvent e) {
			int px = e.getX();
			int py = e.getY();
			Life life = new Life();
			px=life.row;
			py=life.column;
			life.gamefield[px][py]='1';
		}
		
	};

	public GameOfLifeGUI() {
		super();
		m_oMainbox = new Box(BoxLayout.Y_AXIS);
		m_oHeading = new JLabel("Game of Life");
		m_oStart = new JButton("Start");
		m_oBakterien = new JTextArea(50, 20);
		m_oScroll = new JLifePanel();
		m_oScroll.setSize(500, 500);
		

		createFrame();

	}

	protected void createFrame() {
		setSize(800, 600);
		setLocation(100, 100);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		getMainbox().add(Box.createRigidArea(new Dimension(0, 25)));
		getMainbox().add(getHeading());
		getHeading().setAlignmentX(CENTER_ALIGNMENT);
		getMainbox().add(getScroll());
		getScroll().addMouseListener(mouse);
		getMainbox().add(getStart());
		final GameOfLifeGUI gui = this;
		getStart().addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				Thread t = new Thread() {
					public void run() {
						LifePerform.spiele(gui);
					}
				};
				t.setName("Life");
				t.start();

			}
		});
		getStart().setAlignmentY(BOTTOM_ALIGNMENT);
		getStart().setAlignmentX(CENTER_ALIGNMENT);

		this.add(getMainbox());
		setVisible(true);

	}

	public JLabel getHeading() {
		return m_oHeading;
	}

	public Box getMainbox() {
		return m_oMainbox;
	}

	public JButton getStart() {
		return m_oStart;
	}

	public JTextArea getBakterien() {
		return m_oBakterien;
	}

	public JLifePanel getScroll() {
		return m_oScroll;
	}

}

-Life
Java:
package Game;

import java.awt.Graphics;
import java.awt.Point;
import java.util.Random;

public class Life {

	public int row = 30;
	public int column = 30;
	public int coins = row * column / 5;

	public char[][] gamefield = new char[row][column];
	

	public Life() {
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				gamefield[i][j] = '0';

			}

		}

	}
	

	public void randomPlacement() {
		Random rnd = new Random();

		for (int i = 0; i <= coins; i++) {
			int z1 = rnd.nextInt(row);
			int z2 = rnd.nextInt(column);
			gamefield[z1][z2] = '1';
			System.out.println(z1 + ":" + z2);
		}
	}

	public String printGamefield() {
		System.out.println();
		System.out.println();
		String str = "";
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				str += gamefield[i][j];
				System.out.print(" " + (gamefield[i][j] == '1' ? "X" : " "));
			}
			System.out.println();
		}
		System.out.println();
		return str;
	}

	public String nextGeneration() {
		char newWorld[][] = new char[row][column];
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				switch (neighbors(i, j)) {
				case 3:
					if (dead(i, j)) {
						newWorld[i][j] = '1';
					} else if (alive(i, j)) {
						newWorld[i][j] = '1';
					}
					break;

				case 2:
					if (alive(i, j)) {
						newWorld[i][j] = '1';

					} else if (dead(i, j)) {
						newWorld[i][j] = '0';
					}
					break;

				default:
					newWorld[i][j] = '0';
					break;
				}

			}
		}
		for (int i = 0; i < row; i++) {
			for (int j = 0; j < column; j++) {
				gamefield[i][j] = newWorld[i][j];

			}
		}
		return printGamefield();
	}

	public boolean dead(int i, int j) {
		if (gamefield[i][j] == '0') {
			return true;
		} else
			return false;
	}

	public boolean alive(int i, int j) {
		if (gamefield[i][j] == '1') {
			return true;
		} else
			return false;
	}

	public int border(int i) {
		if (i <= 0) {
			return 0;
		} else if (i >= row) {
			return (row - 1);
		} else
			return i;

	}

	private int neighbors(int i, int j) {
		int iNeighbors = 0;
		int iRowStart = border(i - 1);
		int iColumnstart = border(j - 1);

		while (iRowStart <= border(i + 1)) {
			while (iColumnstart <= border(j + 1)) {
				if (alive(iRowStart, iColumnstart)
						&& !((iRowStart == i) && (iColumnstart == j))) {
					iNeighbors++;
				}
				iColumnstart++;
			}
			iRowStart++;
			iColumnstart = border(j - 1);
		}

		return iNeighbors;
	}

	public void paint(Graphics g) {
		for (int row = 0; row < gamefield.length; row++) {
			char[] rowdata = gamefield[row];
			for (int col = 0; col < rowdata.length; col++) {
				if (rowdata[col] == '1')
					g.fillRect(col * 10, row * 10, 9, 9);
				// g.fillRect(x, y, width, height);
			}
		}
	}

}

-JLifePanel

Java:
package Game;

import java.awt.Graphics;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class JLifePanel extends JPanel {

	private Life life;
	

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		if (life != null) {
			life.paint(g);
		}
	}

	public void updateDaten(Life life) {
		this.life = life;
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				JLifePanel.this.repaint();
				
			}
		});

	}
}

und noch -LifePerform
Java:
package Game;

public class LifePerform {

	public static Life life = new Life();
	private static String m_strNewWorld;
	
	
	public static void printNextGeneration(Life l, GameOfLifeGUI gui) {
		while (true) {
			l.nextGeneration();
			gui.getScroll().updateDaten(l);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//gui.getBakterien().setText(strB.toString());
	}
	

	public static void spiele(GameOfLifeGUI gui) {

		life.randomPlacement();
		printNextGeneration(life, gui);
	}

	public static void main(String[] args) {

		new GameOfLifeGUI();

	}


	public static String getNewWorld() {
		return m_strNewWorld;
	}


	public static void setNewWorld(String a_strNewWorld) {
		m_strNewWorld = a_strNewWorld;
	}

}

Hoffe Ihr könnt mir nen kleinen Tipp geben 🙂
 
Hab mir jetzt nicht alles angeschaut, aber ich würde sagen, du willst jeweils auf das letze Element im 2D Array zugreifen. Die haben aber nicht den Index 30 sondern 29. Arrays sind in Java 0-basiert.
 
Also eigentlich möchte ich garnicht auf '30' zugreifen, klicke beliebig in dem Panel, jedoch jedesmal die gleiche Exception bei '30'...
 
Java:
int px = e.getX();
int py = e.getY();
Life life = new Life();
px=life.row; //wieso
py=life.column; //warum
life.gamefield[px][py]='1';

Ohne jetzt weiter geschaut zu haben. Das ist mir bei dem Fehler als erstes aufgefallen. Die ersten 2 Anweisungen sind quasi hinfällig wenn du danach px und py erneut setzt. Du setzt px und py dann auf die maximale Anzahl an Reihen und Spalten und das ist wie mein Vorredner schon bemerkt hat ein Standardfehler. Ein 30er Array hat Indizes von 0-29. Warum überschreibst du px und py mit diesen Grenzwerten? So setzt du die 1 immer genau an der selben Stelle, statt an den Mauskoordinaten.
 
Zuletzt bearbeitet:
Alles kla schonmal vielen Dank, ein Fehler weniger 🙂
Immernoch die gleiche Exception nur nicht mehr mit 30 sondern beliebigen Zahlen.
Ich mach mich mal auf die Suche...🙂
 
du müsstest auch schauen ob die Mauskoordinaten im Bereich des Spielefensters liegen .. und wo die Maus überhaupt anfängt mit zählen, vermutlich nicht exakt auf deinem Spielfeld
 

Neue Themen


Zurück
Oben