Liste nach Übergabe leer, warum?

Collinwood

Mitglied
Hallo Leute, ich steh hierbei total im Wald :suspekt:
Hoffe, ihr blickt durch und könnt mir helfen.

Ich habe da in einer Klasse meine Attribute
Java:
private BeingContainer beingContainer; // beerbt eine ArrayList<Being> //Being = andere, eigene Klasse
private SimulationComposite simulationComposite; //ist ein SWT-Composite
und ich komme dann in einer meiner Methoden an den Punkt wo ich die o.g. Liste/Container mit meinen "Beings" darin an das Composite übergeben möchte:
Java:
System.out.println("Größe der Liste beingContainer in dieser Klasse: "+this.beingContainer.size());
		this.simulationComposite.setBeingList(this.beingContainer);
		System.out.println("Liste wurde übergeben...");
Ausgabe dessen lautet (z.B.):
Größe der Liste beingContainer im LifeController: 42
Liste wurde übergeben...
Der Code im Composite sieht folgendermaßen aus:
Java:
package view;

import java.util.ArrayList;

import model.Being;

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;

/**
 * @author Tobias Keiler
 * @date 09.12.2010
 */
public class SimulationComposite extends Composite {

	/**
	 * @Description
	 */
	private ArrayList<Being> beingList;

	/**
	 * @param parent
	 * @param style
	 */
	public SimulationComposite(Composite parent, int style) {
		super(parent, style);
		this.beingList = new ArrayList<Being>();
		initialize();
	}

	/**
	 * 
	 */
	private void initialize() {
		setSize(new Point(800, 470));
		setLayout(null);
		this.addPaintListener(new PaintListener() {

			@Override
			public void paintControl(PaintEvent arg0) {
				//FIXME syso
				System.out.println("Größe der Liste beingContainer im SimulationComposite: "+SimulationComposite.this.beingList.size());
				if (!SimulationComposite.this.getBeingList().isEmpty()) {
					//FIXME syso
					System.out.println("Liste voll");
					for (Being being : SimulationComposite.this.getBeingList()) {
						// Rectangle rect =
						// SimulationComposite.this.getClientArea();
						arg0.gc.drawOval(being.getPosition().getX(), being
								.getPosition().getY(), 1, 1);
					}
				} else {
					//FIXME syso
					System.out.println("Liste leer");
					arg0.gc
							.drawString("Simulation ist unterbrochen...",
									SimulationComposite.this.getDisplay()
											.getBounds().width / 2,
									SimulationComposite.this.getDisplay()
											.getBounds().height / 2);
				}

			}

		});
	}

	/**
	 * @Description //TODO Describe this one!
	 * @param beingList
	 */
	public void setBeingList(ArrayList<Being> beingList) {
		this.beingList = beingList;
	}

	/**
	 * @Description //TODO Describe this one!
	 * @return //TODO
	 */
	public ArrayList<Being> getBeingList() {
		return this.beingList;
	}

}
// @jve:decl-index=0:visual-constraint="10,10"

... und als Ausgabe bekomme ich zu diesem Objekt zu meinem Erstaunen immer nur:
Größe der Liste beingContainer im SimulationComposite: 0
Liste leer

Mal abgesehen von diesem größeren Fehler, wird zwar der Else-Zweig in der paintControl-Methode durchlaufen, aber den gewünschten String "Simulation ist unterbrochen..." hab ich auch noch nie gesehen!! Wer mir also sagen kann wo es da noch hängt, bitte gerne.
Edit: Hierzu hab ich die Lösung gefunden:
Java:
SimulationComposite.this.getBounds().width / 2
statt
Java:
SimulationComposite.this.getDisplay().getBounds().width / 2
war die Lösung.


Dankeschön vorab,
Collinwood
 
Zuletzt bearbeitet:
1. Tipp wenn was nicht so ist, wie es sein sollte, den debugger nutzen :D
2.
this.beingList = new ArrayList<Being>();
initialize();

So kann sie nur leer sein :D Da du ja hier ne neue (leere) Liste erstellst
 
1. Danke für den Tipp :) Aber in dem Fall seh ich ja auch durch den Debugger einfach nur den Aufruf der nichts bewirkt hat ^^

2. Öhm... schon klar, dass ich da ne neue erstelle. Das mach ich ja auch absichtlich im Konstruktor - danach lebt dieses Objekt ja. Ich lasse genau dieses Objekt bereits in der Klasse mit der void Main an das "Benutzerobjekt" übergeben, und greife ja dann mit set... darauf zu. Diesen Aufruf mit new... würd ich ja generell immer gerne weglassen, aber mit nicht-initialisierten Listen gibts leider immer null-pointer-Exceptions. Also irgendwo MUSS ich ja new sagen... oder? Klar, = null geht auch, aber hat das nicht dieselbe Auswirkung... nochmal: Das Objekt ist bereits konstruiert und lebt, danach wird nix mehr überschrieben.... ich bin leider so schlau wie vorher.
Hier der Auszug aus der Main-Methode
Java:
MainFrame mainFrame = new MainFrame(shell, SWT.NONE);
		mainFrame.setSize(shell.getBounds().width,shell.getBounds().height);
		LifeController lifeController = new LifeController(mainFrame.getSimulationComposite(),mainFrame.getOptionComposite(),o,display);
 
Moin,

also ich sehe es auch so wie MiMi ...
Du erstellst eine neue leere Liste - und fertig!

Beschreib' mal näher, wo sie Deiner Meinung nach mit konkreten Daten gefüllt werden müsste !
Eine solche Stelle sehe ich in Deinem ersten Post nicht ;) (und den zweiten habe ich in diesem Zusammenhang nicht verstanden)

Gruß
Klaus
 
Hi.

@Collinwood: Zeig mal den relevanten Code. Insbesondere da wo du die Ausgaben machst.

Bzw. prüfe mal im Debugger wie oft der Konstruktor der SimulationComposite Klasse aufgerufen wird (sollte ja nur einmal passieren?!). Oder erzeugst du in mainFrame.getSimulationComposite() jedesmal ein neues Objekt?

Gruß
 
Bevor du die set-methode aufrufst, ist doch dieses hier:
Java:
    this.beingList = new ArrayList<Being>();
      initialize();
Somit wird auch nur vor der set-methode initialize aufgerufen und auch nur einmal die paintControl?
Nach dem Aufruf der set-methode, kommt er doch gar nicht mehr in die paintControl-methode? <- sowas koenntest du im debugger pruefen. In welcher Reihenfolge er durch die Methoden geht.

Ablauf:
- neue Liste
- aufruf initialize()
- aufruf paintControl()
- setBeingList

? Oder wird die paintControl immer wieder neu aufgerufen?
 
Hi vfl-freak,

ok ich versuch es step-by-step darzustellen, inklusive allen weiteren Tests die ich bis jetzt unternommen habe.
1. Zunächst der Ablauf der Objekterzeugung vom SimulationComposite:
Java:
//In der "Starter-Klasse", innerhalb der Main-Methode:
MainFrame mainFrame = new MainFrame(shell, SWT.NONE);
//In MainFrame:
this.simulationComposite = new SimulationComposite(this.tabFolder,
				SWT.NONE);
//und dieses Objekt übergebe ich wiederum in der Main-Methode an späterer Stelle zusammen mit anderen Objekten, die ich brauche, an den "LifeController":
LifeController lifeController = new LifeController(mainFrame.getSimulationComposite(),mainFrame.getOptionComposite(),o,display);
Soweit steht fest dass ich mit dem selben Objekt arbeite.

2. Eine Überprüfung durch system-out ergab, dass dieses Objekt definitiv erzeugt wird, bevor es übergeben wurde und ergab des weiteren, dass der Konstruktor definitiv nur einmal durchlaufen wird.

3. Debugger-Screenshots (bitte reinschauen)
Dort habe ich einen Breakpoint gesetzt, wo ich vom LifeController aus
Java:
this.simulationComposite.setBeingList(this.beingContainer);
aufrufe und meine Liste übergebe. Es funktioniert scheinbar tadellos.

Das Problem ist nur, dass ich das ganze dann gerne zeichnen möchte. Dessen Überprüfung leite ich ja dann in SimulationComposite mit
Java:
if (!SimulationComposite.this.getBeingList().isEmpty()) {
ein. Dieser Zweig wird aber nie durchlaufen. Zusammenfassend gesagt: lifeController-Objekt hat ein simulationComposite-Objekt und diesem kann es mit set..() eine Liste übergeben. Dann kommt es definitiv nach der Listenübergabe zum Codeeintritt wo der Inhalt dieser Liste abgefragt wird (das mache ich grundsätzlich wegen nullpointern). Und dort bekomme ich immer gesagt: Liste leer.

Wie gesagt, die Debugger-Screenies sind am interessantesten.
 

Anhänge

  • 1.JPG
    1.JPG
    160,1 KB · Aufrufe: 18
  • 2.JPG
    2.JPG
    124,4 KB · Aufrufe: 13
  • 3.JPG
    3.JPG
    129,2 KB · Aufrufe: 11
  • 4.JPG
    4.JPG
    162,5 KB · Aufrufe: 8
  • 5.JPG
    5.JPG
    161,6 KB · Aufrufe: 17
Hallo nochmal,

danke auch an die weiteren Antworten von deepthroat und mimi, hatte euch beide gar nicht gesehen, muss wohl während meiner Antwort passiert sein.
@deepthroat: Wie schon beschrieben, das mit den Aufrufen ist gecheckt...
@MiMi: Die initialize() wird korrekterweise ein einziges mal ausgeführt, genauso wie new Arraylist()... danach ist die paintControl in einem stetig lauschenden Zustand und sie funktioniert auch tadellos. Ich kam ja von Anfang an immer in den else-Zweig. Nur die Überprüfung if(listeleer) verhinderte ein fortkommen an der richtigen Stelle. Ich habe mittlerweile, um weiterprogrammieren zu können, die Liste temporär statisch ausgelagert, das zeichnen meiner Objekte funktioniert prima.
aktueller Klassencode:
Java:
package view;

import java.awt.Color;
import java.util.ArrayList;

import model.Being;

import options.Options;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

/**
 * @author Tobias Keiler
 * @date 09.12.2010
 */
public class SimulationComposite extends Composite {

	/**
	 * @Description
	 */
	protected ArrayList<Being> beingList;
	/**
	 * @Description
	 */
	protected ArrayList<Rectangle> rectangleList;

	/**
	 * @param parent
	 * @param style
	 */
	public SimulationComposite(Composite parent, int style) {
		super(parent, style);
		this.beingList = new ArrayList<Being>();
		this.rectangleList = new ArrayList<Rectangle>();
		initialize();
	}

	/**
	 * 
	 */
	private void initialize() {
		setLayout(null);
		this.addPaintListener(new PaintListener() {

			@Override
			public void paintControl(PaintEvent arg0) {
				//FIXME syso
				System.out.println("Größe der Liste beingContainer im SimulationComposite: "+getBeingList().size());
				//if (!SimulationComposite.this.getBeingList().isEmpty()) {
				//FIXME wieder wegmachen nur test
				SimulationComposite.this.rectangleList.clear();
				if(!Options.beingList.isEmpty()) {
					//FIXME syso
					System.out.println("Liste voll");
					//for (Being being : SimulationComposite.this.getBeingList()) {
					//FIXME wieder wegmachen nur test
					for (Being being : Options.beingList) {
						if(being.getAge()<3) {
							arg0.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_RED));
						}
						else {
							arg0.gc.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
						}
						arg0.gc.drawOval(being.getPosition().getX(), being
								.getPosition().getY(), 10, 10);
						Rectangle r = new Rectangle(being.getPosition().getX(),being.getPosition().getY(),10,10);
						SimulationComposite.this.rectangleList.add(r);
					}
				} else {
					//FIXME syso
					System.out.println("Liste leer");
					arg0.gc
							.drawString("Simulation ist unterbrochen...",
									SimulationComposite.this
											.getBounds().width / 2,
									SimulationComposite.this
											.getBounds().height / 2);
				}
				Listener mouseListener = new Listener() {

					@Override
					public void handleEvent(Event event) {
						switch(event.type) {
						case SWT.MouseEnter: 
						case SWT.MouseMove:
							for (Rectangle rectangle : SimulationComposite.this.rectangleList) {
								if (rectangle.contains(event.x,event.y)) {
									Being being = Options.beingList.get(SimulationComposite.this.rectangleList.indexOf(rectangle));
									String gender = "weiblich";
									if(being.isGender()) {
										gender = "männlich";
									}
									String text = "Alter: "+being.getAge()
									+"\nSpezies: "+being.getClass().toString()
									+"\nGeschlecht: "+gender;
									if(!(text.equals(SimulationComposite.this.getToolTipText()))) {
										SimulationComposite.this.setToolTipText(text);
									}
									return;
								}
							}
							SimulationComposite.this.setToolTipText(null);
							break;
						}
						
					}
					
				};
				SimulationComposite.this.addListener(SWT.MouseMove, mouseListener);
				SimulationComposite.this.addListener(SWT.MouseEnter, mouseListener);
			}

		});
	}

	/**
	 * @Description //TODO Describe this one!
	 * @param beingList
	 */
	public void setBeingList(ArrayList<Being> beingList) {
		this.beingList = beingList;
	}

	/**
	 * @Description //TODO Describe this one!
	 * @return //TODO
	 */
	public ArrayList<Being> getBeingList() {
		return this.beingList;
	}

}
Im Anhang ist ein aktueller Screenshot der Applikation. Es funktioniert ja schön, aber ich möchte das nicht mit dem static-****** :D Das wirft das gesamte OO-Konzept übern Haufen, dafür studier ich nicht.

Ich freu mich schon auf weitere Antworten, bin euch sehr dankbar!
 

Anhänge

  • progscreen.JPG
    progscreen.JPG
    193,1 KB · Aufrufe: 35
Zurück