Sieht aus wie ein "Call by Referece/Call by Value"

Status
Nicht offen für weitere Antworten.

netz-rack.c

Mitglied
Hallo,

ich habe das Laden von Stichworten aus einer Datenbank in eine JList vorsorglich in einen SwingWorker ausgelagert, da Datenbaken und Netzwerke ja bekanntlich etwas lahm sein können.

Damit dieser SwingWorker nun die Liste füllen kann, übergebe ich seinem Konstruktor das Model der Liste:
Code:
sw = new AllStw((StichwortListModel)getAllStwList().getModel(), werk);

Das Ausführen übernimmt eine zentrale Status-Klasse. (Deren Funktionalität sichergestellt ist, da andere SwingWorker problemlos ausgeführt werden)

Wie ich an den Log-Daten erkennen kann, holt sich der SwingWorker die richtigen Daten aus der Datenbank und gibt beim Ändern des Models (wieder im EDT) keinerlei Fehler aus.

Jedoch kommen diese Änderungen nie auf der Oberfläche an!

Das hat mich vermuten lassen, dass das Model an irgendeiner Stelle nicht verändert, sondern neu initialisiert wird.

Wo könnte das passieren?

Code:
public class AllStw extends SwingWorker<LinkedList<Stichwort>, Stichwort> implements DB_settings {
	
	private static Logger log = BDBi.getLogger();
	private LinkedList<Stichwort> usedStw;
	private StichwortListModel model;
	
	public AllStw (StichwortListModel model, Kuenstler usedKuenstler) {
		this.model = model;
		usedStw = new LinkedList<Stichwort>(usedKuenstler.getVknStw());
	}
	
	public AllStw (StichwortListModel model, Werk usedWerk) {
		this.model = model;
		usedStw = new LinkedList<Stichwort>(usedWerk.getVerknStw());
	}
	
	public AllStw (StichwortListModel model, Werk usedWerk, Kuenstler usedKuenstler) {
		this.model = model;
		usedStw = new LinkedList<Stichwort>(usedWerk.getVerknStw());
		usedStw.addAll(usedKuenstler.getVknStw());
	}
	


	@Override
	protected LinkedList<Stichwort> doInBackground() throws Exception {
		
		LinkedList<Stichwort> res = new LinkedList<Stichwort>();
		Connection c = DriverManager.getConnection("proxool.BDB");
		log.entering(this.getClass().getSimpleName(), "doInBackgrund");
					
		try {
			ResultSet rs = c.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY)
								.executeQuery(""+ 
									" SELECT" +
									"  s.*" +
									" FROM" +
									"  "+DB_SCHEMA+".stichwort AS s" +
									" ORDER BY" +
									"  wort");
			
			rs.last();
			double progressPerRow = rs.getRow() / 100;
			
			
			rs.beforeFirst();  //cursor wieder vor die erste Reihe bewegen, damit mann alle Reihen der Reihe nach abgehen kann
			
			while (rs.next()) {
				if(this.isCancelled())
					return null;
				
				Stichwort s = new Stichwort(rs.getString("wort"), //wort
						rs.getString("abkuerzung"), //abk.
						rs.getInt("stichw_id") //id
						);
				
				if (!usedStw.contains(s)) {  
					res.add(s);
					
					publish(s);
				}
				this.setProgress((int)(this.getProgress() + progressPerRow));
				
				
			}
		} finally {
			SQLWarning w = c.getWarnings();
			if(w!=null)
				log.fine("SQL Warning: " + w.getMessage());
			c.close();
			log.finer("Verbindung zum Lesen aller Stichworte geschlossen.");
		}
		log.exiting(this.getClass().getSimpleName(), "doInBackground", res);
		return res;
	}


	@Override
	protected void process(List<Stichwort> chunks) {
		log.entering(this.getClass().getSimpleName(), "process", chunks);
		for (Stichwort stw : chunks) {
			model.addElement(stw);
		}
		log.exiting(this.getClass().getSimpleName(), "process");
	}

	@Override
	protected void done() {
		try {
			LinkedList<Stichwort> r = get();
			
			log.entering(this.getClass().getSimpleName(), "done", r);
			
			for (Stichwort stichwort : r) {
				if(!model.contains(stichwort)){
					model.addElement(stichwort);
				}else {
					log.fine("Already in Model: \""+stichwort+"\"");
				}
			}
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		log.exiting(this.getClass().getSimpleName(), "done");
	}

}

(Nicht über den extensiven gebrauch des Loggers wundern, ich verzweifel schon länger :? )

Zum StichwortListModel sei noch hinzugefügt, dass es sich um eine Klasse Handelt, die das DefaultListModel überschreibt und als Speicher eine LinkedList<Strichwort> benutzt.

soweit mein Problem, sieht Irgendwer eine Lösung?

MfG
Carsten


EDIT: Oder könnte das was mit der Sichtbarkeit des Models zu tun haben, das eine private Membervariable ist, und in einem anderen Paket steht (zusammen mit der JList) ??
 
S

SlaterB

Gast
muss es denn unbedingt eine DB sein?
kannst du einfach
protected LinkedList<Stichwort> doInBackground() throws Exception {
new LinkedList();
list.add(Stichwort "Test");
}
zurückgeben?

oder funktioniert es in diesem einfachen Fall? das wäre eine wichtige Info,


genauso den SwingWorker und sowieso alles mögliche weglassen,

funktioniert statt
sw = new AllStw((StichwortListModel)getAllStwList().getModel(), werk);
und hunderte Zeilen Code
bereits
((StichwortListModel)getAllStwList().getModel()).add("Test")
ja oder nein?

das sind die sinnvollen Vorgehensweisen..
 

kleiner_held

Top Contributor
Dein StichwortListModel feuert die richtigen TableModelEvents wenn du addElement(...) aufrufst?

PS: Ansonsten versuche bitte mal dein Problem auf ein "Kurzes, Selbständiges, Kompilierbares Beispiel" (siehe FAQ) zu reduzieren. Wenn dein Datenbank-Statement funktioniert hat der ganze DB Kram hier nichts zu suchen.
 

netz-rack.c

Mitglied
hmn, das mit dem Event klingt interessant (neu) ,...
d.H. mein Model ist parzifistisch und feuert gar nichts, könnte ne erklärung sein!

wo gibt es denn ne doku was für events die jeweiligen Methoden verschießen?

(imho find ich das in der "normalen" API nicht ???:L )
 

netz-rack.c

Mitglied
Oh, zum "DB-Kram":

bevor ichs vergesse, das alles, hat schon mal funktioniert, als der swingworker noch eine eingekapselte Klasse war und mit einem DefaultListModel gearbeitet hat.

(sry für den Doppelpost)
 

netz-rack.c

Mitglied
hmn, also, das Problem ist als gelöst anzusehen!

Der Fehler lag bei dem ListModel, dass keine Events feuerte. :oops:


Aber eine Frage bleibt, woran erkenne ich welche methode (im Original) welche Events abschießt?

(Für diesen Fall ists klar, aber wie siehts allgemein aus, ich möcht ja was lernen :### )
 

kleiner_held

Top Contributor
Schau dir einfach mal alle Methoden an, die die Oberklassen DefaultListModel and AbstractListModel haben und deren Name mit fire anfaengt. Die Namen und JavaDoc lassen eigentlich keine Fragen offen. Wenn du in deinem ListModel die Datenhaltung selbst implementierst (in einer eigenen LinkedList) solltest du auch nicht von DefaultListModel erben sondern von AbstractListModel.
 
S

SlaterB

Gast
DefaultListModel

Code:
 /**
     * Sets the component at the specified <code>index</code> of this 
     * list to be the specified object. The previous component at that 
     * position is discarded.
     * 


     * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index 
     * is invalid.
     * <blockquote>
     * [b]Note:[/b] Although this method is not deprecated, the preferred
     *    method to use is <code>set(int,Object)</code>, which implements the 
     *    <code>List</code> interface defined in the 1.2 Collections framework.
     * </blockquote>
     *
     * @param      obj     what the component is to be set to
     * @param      index   the specified index
     * @see #set(int,Object)
     * @see Vector#setElementAt(Object,int)
     */
    public void setElementAt(Object obj, int index) {
	delegate.setElementAt(obj, index);
	fireContentsChanged(this, index, index);
    }

    /**
     * Deletes the component at the specified index.
     * 


     * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index 
     * is invalid.
     * <blockquote>
     * [b]Note:[/b] Although this method is not deprecated, the preferred
     *    method to use is <code>remove(int)</code>, which implements the 
     *    <code>List</code> interface defined in the 1.2 Collections framework.
     * </blockquote>
     *
     * @param      index   the index of the object to remove
     * @see #remove(int)
     * @see Vector#removeElementAt(int)
     */
    public void removeElementAt(int index) {
	delegate.removeElementAt(index);
	fireIntervalRemoved(this, index, index);
    }

    /**
     * Inserts the specified object as a component in this list at the 
     * specified <code>index</code>.
     * 


     * Throws an <code>ArrayIndexOutOfBoundsException</code> if the index 
     * is invalid.
     * <blockquote>
     * [b]Note:[/b] Although this method is not deprecated, the preferred
     *    method to use is <code>add(int,Object)</code>, which implements the 
     *    <code>List</code> interface defined in the 1.2 Collections framework.
     * </blockquote>
     *
     * @param      obj     the component to insert
     * @param      index   where to insert the new component
     * @exception  ArrayIndexOutOfBoundsException  if the index was invalid
     * @see #add(int,Object)
     * @see Vector#insertElementAt(Object,int)
     */
    public void insertElementAt(Object obj, int index) {
	delegate.insertElementAt(obj, index);
	fireIntervalAdded(this, index, index);
    }
usw.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen


Oben