Geänderte Variable in anderen Methoden unverändert

Thunderhit

Grünschnabel
Hi, ich will PDFBox nutzen, um Daten aus einer PDF, u.a. auch die Position, auszulesen. Dazu habe ich die Methode "processTextPosition" gefunden, die laut Kommentar wohl per Event gestartet wird. Darin werte ich die Positionen aus und schreibe sie in eine Liste. Wenn die Methode allerdings fertig ist und ich auf die Liste in einer anderen Methode zugreifen will, ist sie leer, als ob sie nie verändert worden wäre. Jedoch hat die Event Methode immer die Daten vom letzten Durchgang, da sie sehr oft hintereinander aufgerufen wird. Ich habe mir auch die Größe der Liste ausgeben lassen, in der Event Methode wächst sie. Woran liegt es also, dass ich auf die Daten nicht zugreifen kann in anderen Methoden?
Ach ja, die Verarbeitung geschieht beim Aufruf von "printer.processStream(page, page.findResources(), page.getContents().getStream());".

Hier der Code:

Java:
package test;

import org.apache.pdfbox.exceptions.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDStream;
import org.apache.pdfbox.util.PDFTextStripper;
import org.apache.pdfbox.util.TextPosition;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;


public class TestAnfang extends PDFTextStripper {
	
	private List<Absatz> liste = new LinkedList<Absatz>();
	
	public TestAnfang() throws IOException {

		super.setSortByPosition(true);
		//liste = new LinkedList<Absatz>();
	}

	private void Test() throws Exception {

		String file = "Y:\\test.pdf";
		PDDocument document = null;
		try {
			document = PDDocument.load(file);
			if (document.isEncrypted()) {
				try {
					document.decrypt("");
				} catch (InvalidPasswordException e) {
					System.err
							.println("Error: Document is encrypted with a password.");
					System.exit(1);
				}
			}
			TestAnfang printer = new TestAnfang();
			List allPages = document.getDocumentCatalog().getAllPages();
			for (int i = 0; i < allPages.size(); i++) {
				
				if (i==8){
					PDPage page = (PDPage) allPages.get(i);
					System.out.println("Processing page: " + i);
					PDStream contents = page.getContents();
					if (contents != null) {
						this.liste.add(new Absatz());

						printer.processStream(page, page.findResources(), page
								.getContents().getStream());
					}
				}
			}
			
			System.out.println("Liste "+ this.liste.size());
		} finally {
			if (document != null) {
				document.close();
			}
		}
	}
	
	public static void main(String[] args)throws Exception{
		TestAnfang test = new TestAnfang();
		test.Test();
		System.out.println(test.getListe().size());
	}

	public List<Absatz> getListe(){
		return liste;
	}
	/**
	 * A method provided as an event interface to allow a subclass to perform
	 * some specific functionality when text needs to be processed.
	 * 
	 * @param text
	 *            The text to be processed
	 */
	protected void processTextPosition(TextPosition text) {

		Absatz aktuell;
		if (this.liste.size() == 0){
			aktuell = new Absatz();
		}
		else{
			aktuell= this.liste.get(this.liste.size()-1);
		}
		/* wenn noch kein Absatz vorhanden ist, hier erstellen*/
		if (aktuell.getText() == null){
			aktuell.setxAnfang(text.getXDirAdj());
			aktuell.setyEnde(text.getYDirAdj());
			aktuell.setText(text.getCharacter());
			aktuell.setxEnde(text.getXDirAdj()+text.getWidthDirAdj()); //getWidthDirAdj oder getWidth geben in Tests selben Output aus
			aktuell.setyEnde(aktuell.getyAnfang()+text.getHeight());
			this.liste.add(aktuell);
		}
		else{
			/* selbe Zeile*/
			if (aktuell.getyAnfang() == text.getYDirAdj()){
				aktuell.setxEnde(text.getXDirAdj()+text.getWidthDirAdj());
				aktuell.setyEnde(text.getY()+text.getHeightDir());
				aktuell.setText(aktuell.getText()+text.getCharacter());
			}
			else{
				Absatz neu = new Absatz();
				neu.setxAnfang(text.getXDirAdj());
				neu.setyEnde(text.getYDirAdj());
				neu.setText(text.getCharacter());
				neu.setxEnde(text.getXDirAdj()+text.getWidthDirAdj()); //getWidthDirAdj oder getWidth geben in Tests selben Output aus
				neu.setyEnde(neu.getyAnfang()+text.getHeight());
				this.liste.add(neu);
			}
		}
		System.out.println(liste.size());
		/*System.out.println("[" + text.getXDirAdj() + ","
				+ text.getYDirAdj() + " fs=" + text.getFontSize() + " scale=" + text.getXScale() + " width="
				+ text.getWidthDirAdj() + " widthspace=" + text.getWidthOfSpace()+ "]" + text.getCharacter());*/
		
		
	}

	/**
	 * This will print the usage for this document.
	 */
	private static void usage() {
		System.err
				.println("Usage: java org.apache.pdfbox.examples.pdmodel.PrintTextLocations <input-pdf>");
	}
}
 
Bevor ich das jetzt auf Papier durchmache, solltest du lieber einen Debugger verwenden.
Entweder die Bedingung zum Füllen der Liste wird nicht erfüllt, oder an anderer Stelle wird der Inhalt gelöscht.
Beides kannst du mittels Debugger echt gut herausfinden
 
Ich habe mir per Debugger die liste angesehen. Einmal bevor die Methode "processTextPosition" aufgerufen wurde, einmal danach. Das seltsame dabei war, dass sie in der Methode processTextPosition auf einmal eine völlig andere ID hatte und ich wohl da durch nicht darauf zugreifen kann, nur weiß ich nicht wieso. Die liste ist nur in dieser Klasse definiert, die Superklasse kennt sie nicht; daher sollte sie sich auch nicht ändern...
Die ID ist die selbe vor- und nach dem Aufruf, nur währenddessen nicht.
Ich weiß auch, dass der Code klappt, hinsichtlich dem Füllen der Liste... nur scheint das Problem wirklich zu sein, dass die ID sich ändert und ich weiß nicht warum.
 
Wenn die ID anders ist, dann wurde ein neues Objekt referenziert.
Wenn du wirklich Schritt für Schritt den Debugger nutzt, dann solltest du sehen wo es passiert.
 
Du erzeugst in Zeile 39 eine neue Instanz von TestAnfang. Aus der Erstinstanz rufst von dieser Instanz die Methode processStream auf, die natürlich die Liste der Zweitinstanz füllt.Kommentier mal Z39 aus und ruf in Z50 this.processStream(..) auf. Oder lass Dir von printer die Liste zurückgeben.
 
Ja, danke. Hab die Nachricht leider erst heut früh von dir gelesen, dabei fiel sie mir heut morgen nach dem Aufstehen ein :) danke nochmals.
 
Zurück