Eclipse RCP: View updaten

Status
Nicht offen für weitere Antworten.

bschaefer

Mitglied
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?

Code:
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.
 
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.
 
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?
 
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.
 
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.
 
Hier mal der Code:

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 ...
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben