org.w3c.dom.Document einem TextEditor übergeben

darie17

Grünschnabel
Hallo zusammen,

ich befinde mich in der folgenden Situation: es gibt einen MultiPageEditor, der als Eingabe eine XML-Datei bekommt und welcher 2 Seiten hat - die erste wo die XML-Datei als Plaintext dargestellt wird und die zweite, wo die Datei als ein Tree dargestellt wird. In dieser zweiten Seite kann man den Tree per Rechtsklick ändern (zB. Element aus dem Baum löschen).

Ich sollte noch sagen, dass ich DOM benütze, um XML zu parsen und dass ich mir gedacht habe, direkt auf das org.w3c.dom.Document - Objekt zu arbeiten (also alle Änderungen werden auf das Document-Objekt durchgeführt, die Views bekommen dann einen neuen Input und somit werden die Änderungen überall sichtbar). D.h., wenn ich z.B. ein Element aus dem Tree weglösche und zum "SourceCode" - View (erste Ansicht, als XML Quelltext) wechsele, sollte ich den Input für diese Seite ändern (durch die setInput() Methode).

Hier mein Problem: ich habe ein org.w3c.dom.Document - Objekt in der Hand und möchte es dem TextEditor irgendwie übergeben (weil die Klasse, die den Quelltexteditor darstellt vor der Klasse TextEditor erbt). Frage ist wie?... Die setInput() Methode eines Objektes vom Typ TextEditor braucht ein Parameter vom Typ IEditorInput, und das habe ich gar nicht. Wie teile ich denn der ersten Seite meines MultiPageEditors mit, dass sich der Inhalt geändert hat und dass ich ihn ein neues org.w3c.dom.Document - Objekt übergeben möchte?
 
Hallo,

ganz einfach: du verpackst dein Document Objekt in eine eigene simple Implementierung von IEditorInput. Dort kannst du entweder die getAdapter() Methode entsprechend implementieren oder eine eigene Methode (z.B. getDocument()) schreiben, damit der TextEditor auch den Zugriff auf das Document Object hat. Das setzt natürlich voraus, dass du ebenfalls eine eigene Implementierung von dem TextEditor hast.

Grüße
Vincent
 
Hi Vincentius,

vielen Dank für deine Antwort. Ich habe versucht deinen Vorschlag zu verstehen, aber habe es irgendwie nicht hingekriegt. Hier ist was ich versucht habe:

- ich habe mir eine eigene Klasse definiert, die die Interface IEditorInput implementiert
- dann habe ich in dieser Klasse ein Objekt vom Typ org.w3c.dom.Document, für den ich einen setter und einen getter generiert habe

Und jetzt meine Fragen:

- brauche ich in dieser Klasse einen Konstruktor? Wenn ja, rufe ich es so auf? -->

Code:
textEditor.setInput(new MyOwnIEditorInput(document));
, wobei document ein Objekt vom Typ org.w3c.dom.Document ist

- lasse ich die Methoden getImageDescriptor(), getName(), getPersistable(), getToolTipText(), exists() ohne Implementierung? Weil die aus der Interface stammen.
- außerdem ist mir noch nicht klar, was mit der getAdapter() Methode gemacht werden soll, die API ist für mich persönlich nicht so selbsterklärend... ("...Returns an object which is an instance of the given class associated with this object...")

...und hier die Klasse, die ich bis her habe:

Code:
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;
import org.w3c.dom.Document;

public class XMLEditorInput implements IEditorInput {
	
	private Document domDocument;

	@Override
	public boolean exists() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getName() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public IPersistableElement getPersistable() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getToolTipText() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object getAdapter(Class adapter) {
		// TODO Auto-generated method stub
		return null;
	}

	/**
	 * @return the domDocument
	 */
	public Document getDomDocument() {
		return domDocument;
	}

	/**
	 * @param domDocument the domDocument to set
	 */
	public void setDomDocument(Document domDocument) {
		this.domDocument = domDocument;
	}

}

Und darunter die eigene Klasse, die von TextEditor erbt (colorManager ist hier unwichtig, aber ich habe es mitkopiert):

Code:
import org.eclipse.ui.editors.text.TextEditor;

import [ein paar meiner eigenen Klassen]

public class XMLEditor extends TextEditor {

	private ColorManager colorManager;

	public XMLEditor()
	{
		super();
		colorManager = new ColorManager();
		setSourceViewerConfiguration(new XMLConfiguration(colorManager));
		setDocumentProvider(new XMLDocumentProvider());
	}
	
	protected void createActions()
	{
		super.createActions();
	}
	
	public void dispose() {
		colorManager.dispose();
		super.dispose();
	}

}

Vielen Dank!
 
Zuletzt bearbeitet:
Hallo,

ok, das geht schon in die richtige Richtung.

- brauche ich in dieser Klasse einen Konstruktor? Wenn ja, rufe ich es so auf? -->
Ja, ich würde auch das Document Objekt im Konstruktor des EditorInputs übergeben.

- lasse ich die Methoden getImageDescriptor(), getName(), getPersistable(), getToolTipText(), exists() ohne Implementierung? Weil die aus der Interface stammen.
Normalerweise kannst du die meisten Methoden leerlassen bzw. mit default Rückgabewerten versehen.

- außerdem ist mir noch nicht klar, was mit der getAdapter() Methode gemacht werden soll
Ich kann hier nicht den ganzen Sinn und Zweck von Eclipse Adapter Pattern erklären, schau dir am besten einen geeigneten Artikel zu dem Thema an (z.B. den hier). Jedenfalls kannst du die getAdapter()-Methode dafür verwenden, um das darunterliegende Document Objekt zu liefern als Alternative zur getDomDocument()-Methode.

In deiner Klasse XMLEditor müsstest du noch irgendeine Methode überschreiben, wo der EditorInput gesetzt wird (ich vermute, das ist die setInput()-Methode). Dort kannst du dann das Input-Objekt auf XMLEditorInput kasten und das Document Objekt holen, oder gleich die getAdapter()-Methode benutzen (wenn die implementiert ist), dann kannst du dir das Kasten sparen. Anschließend kannst du den Content des Document Objekts als Input des XMLEditors setzen, wie genau du das anstellst, musst du schon selber schauen :)

Grüße
Vincent
 
Hallo Vincentius,

vielen Dank noch ein Mal. Ich glaube du hast Recht, irgendwas fehlt noch in meiner Klasse, die von TextEditor erbt.
Inzwischen habe ich auch auf eclipse.org ein paar Antworten zu meiner Frage bekommen, hier den Link dazu: http://www.eclipse.org/forums/index.php?t=msg&th=165960&start=0&. Da haben sich merhere Leute die Meinung dazu geäussert. Ich habe auch dort im Forum noch einige Codestücke geschrieben.
Weil ich bin bis zu dem Punkt angekommen, wo alles (theoretisch) funktionieren sollte. Es hat aber nicht, wegen einem Fehler was keine Exception generiert. Wenn du Zeit hast, schau dir mal am Besten mein letzter Beitrag in der o.g. Diskussion. Da ist auch ein Link zu einem Bild mit was mir rauskommt, wenn ich diese Idee implementiere.

Wenn du denkst, dass ich was falsch gemacht habe, oder dass irgendwas fehlt, würde ich mich freuen, wenn du es mir mitteilen würdest.

Danke für deine Zeit!
 
Hallo,

hast du schon in der .log Datei in dem Workspace von deiner Applikation nachgeschaut, ob da eventuell eine Exception rausgeschrieben wurde? Ansonsten hat der Typ aus dem Eclipse Community Forum schon recht: du musst Schritt-für-Schritt debuggen, um die Ursache des Fehlers rauszukriegen.

Aber jetzt mal eine grundsätzliche Frage. Du hast einen TextEditor, dem du einen EditorInput übergibst, der wiederum ein org.w3c.dom.Document Objekt enthält und du erwartest, dass der Editor weiss, wie er es darstellen soll? Ich meine, woher soll er das wissen? Ich glaube, ich habe schon mal angedeutet, dass du in deiner TextEditor Implementierung selbst dafür sorgen musst, dass der Inhalt von deinem Document Objekt entsprechend angezeigt wird. Ich gebe dir einen Tipp: schau dir IDocumentProvider an, ich glaube, das ist der Schlüssel zur Lösung des Problems.

Grüße
Vincent
 
Zurück