# Eclipse RCP: View updaten



## bschaefer (2. Mai 2008)

Hallo zusammen!

Folgende Situation: Ich habe in meiner Eclipse-RCP-Anwendung eine View, die einen File und einen String als Attribut hat und das Bild aus dem File mit dem String darunter darstellt. Für File und String gibt es noch einen Setter, sodass er zur Laufzeit verändert werden kann. Klappt auch beim Start alles, wie kann ich die View dazu bringen, sich zu aktualisieren, nachdem ich den String und/oder das File geändert habe? 


```
public class TestView extends ViewPart {

  public static final String ID = "TestView";

  private File imageFile;

  private String imageName;

  public TestView() {
	
  }

  public void createPartControl( Composite parent ) {
    final Image image = new Image( Display.getDefault(), imageFile.getAbsolutePath() );
    Canvas imageCanvas = new Canvas( parent, SWT.BORDER );
    imageCanvas.addPaintListener( new PaintListener() {
      public void paintControl( PaintEvent e ) {
        if ( previewImage == null ) {
          e.gc.drawString( "Error: No image", 0, 0 );
        } else {
          e.gc.drawImage( previewImage, 0, 0 );
        }
      }  
    });
    Label imageLabel = new Label( parent, SWT.CENTER );
    imageLabel.setText(imageName);
  }

  public void setFile( File imageFile ) {
    this.imageFile = imageFile;
  }

  public void setName( String imageName ) {
    this.imageName = imageName
  }
```

So sieht die Klasse (etwas verkürzt) aus. Bin für jede Hilfe dankbar, vielleicht benutze ich die View auch ganz falsch.


----------



## Wildcard (3. Mai 2008)

> wie kann ich die View dazu bringen, sich zu aktualisieren, nachdem ich den String und/oder das File geändert habe?


Indem du ihr das mitteilst.


----------



## bschaefer (5. Mai 2008)

> Indem du ihr das mitteilst.



Ja, ganz toll. Spitzfindig sein kann ich auch alleine. Leider hat ein Viewpart keine update()-Methode oder sowas. Ein repaint() und update() der einzelnen Komponenten bringt auch nichts.


----------



## Wildcard (5. Mai 2008)

Das hat nichts mit Spitzfindig zu tun. Du musst eine Methode anbieten die dann aufgerufen wird, oder dir ein Observer Konzept überlegen.
Nachtrag:
Vielleicht habe ich gerade dein Problem verstanden. Du denkst, wenn sich irgendwann die Datei und/oder der String ändern, würde sich beim nächsten Zeichnen des ViewParts auch das Ergebnis ändern?
Ein String kann sich gar nicht verändern, er ist unveränderlich.
Eine File Objekt ist nur ein Handle, das sich ebenfalls nicht verändert, höchstens der Inhalt ändert sich, das Handle bekommt davon aber nichts mit.
Du musst also aktiv bescheid sagen, ein 'refresh' reicht nicht.


----------



## bschaefer (5. Mai 2008)

Das war schon klar. Ich dachte nur, es gäbe einen Weg, dass sich der Viewpart einfach mit den aktuell gesetzten Werten neu aufbaut. Also doch "zu Fuß", also eine Refresh-Methode selbst zu schreiben, die das Ding leer macht und neu aufbaut?

Edit:
Hab das dann mal so probiert, klappt jedoch nur, wenn ich das Fenster nachher von Hand verändere, sonst erscheinen die Komponenten nicht. Gibt es eine Möglichkeit, diesen Event (ich denke mal, ein Paint-Event) auszulösen?


----------



## Wildcard (5. Mai 2008)

Ach so, also du rufst wenn sich was änder setFile und setName auf?

Leg einen Member Composite parent an, den du in createControl befüllst.
In den setter rufst du dann parent.redraw() auf. Wenn ein neues File gesetzt wird, brauchst du auch ein neues Image, also dafür eine Methode anlegen und ein neuer Member für Image.
Das mit dem Image geht so in SWT übrigens nicht, Images müssen disposed werden, sonst bist du sehr schnell out of handles/memory.


----------



## bschaefer (5. Mai 2008)

Danke für den Hinweis. Das parent.redraw() bewirkt in dem Fall jedoch nichts. Erst nach der Größenänderung per Maus wird etwas dargestellt.


----------



## Wildcard (5. Mai 2008)

Wie sieht dein Code aktuell aus?


----------



## bschaefer (5. Mai 2008)

Hier mal der Code:


```
public class TestView extends ViewPart {

	public static final String ID = "TestView";

	private String imageName;
	private File imageFile;
	private Composite parent;
	private Canvas topCanvas;
            private final Image previewImage;

	public TestView() {
	
	}

	@Override
	public void createPartControl(Composite parent) {
		this.parent = parent;
	}
	
	public void refresh() {
		FillLayout fillLayout = new FillLayout();
		parent.setLayout(fillLayout);
		if (topCanvas != null) {
                                    Control[] controls = topCanvas.getChildren();
		            for (Control control: controls) {
			control.dispose();
		}
			topCanvas.dispose();
		}
                        if (previewImage != null) {
                                    previewImage.dispose();
                        }
		topCanvas = new Canvas(parent, SWT.NONE);
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		topCanvas.setLayout(gridLayout);
		previewImage = new Image(Display.getDefault(), imageFile.getAbsolutePath());
		Canvas previewCanvas = new Canvas(topCanvas, SWT.BORDER);
		previewCanvas.setLayoutData(new GridData(GridData.FILL_BOTH));
		previewCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				if (previewImage == null) {
					e.gc.drawString("Error: No image", 0, 0);
				} else {
					e.gc.drawImage(previewImage, 0, 0);
				}
			}
		});
		Label idLabel = new Label(topCanvas, SWT.CENTER);
		idLabel.setText(name);
		parent.redraw();
		parent.update();
	}
	
            public void setFile( File imageFile ) { 
                        this.imageFile = imageFile; 
            } 

            public void setName( String imageName ) { 
                        this.imageName = imageName 
            }

	@Override
	public void dispose() {
		previewImage.dispose();
	}

}
```

Sollte jetzt so funktionieren, dass immer refresh() aufgerufen werden muss, wenn sich was geändert hat.

Edit:
Eigentlich sollten die Einrückungen nicht so konfus sein ...


----------



## Wildcard (5. Mai 2008)

Wenn du die Kinder veränderst musst du in jedem Fall parent.layout aufrufen.


----------



## bschaefer (5. Mai 2008)

Super, jetzt klappt das!   :applaus: 
Danke vielmals, jetzt bin ich schonmal einen Schritt weiter! :toll:


----------

