SWT Redraw

Rainbow

Bekanntes Mitglied
Hallo,
ich hab ein Problem mit meiner Oberfläche, die ich mit SWT erstellt habe.

Ich habe so eine Art Parallelogramm gezeichnet, das heißt ich habe 4 Punkte bestimmt und dann gc.drawPolygon(int[] points) gemacht.
Jetzt ist mein Problem, das sich die Hintergrundfarbe von dem Polygon quasi ständig ändern kann. Jetzt weiß ich nicht wie ich das realisieren soll.
Momentan mache ich es so, das wenn sich was ändert, zeichne ich mit gc.fillPolygon drüber...da bekomm ich aber irgendwann eine Exception mit "no more handles"....so weit ich das verstehe ist das, weil die sachen nie disposed werden.

Dann habe ich mir überlegt irgendwie die gc.redraw Methode zu benutzen, der man einen Punkt x und y und width und length übergegebn kann...das ist aber in meinem Fall auch doof, weil ich ein damit ein rechteck neu zeichne, was ich gar nicht habe. Ich möchte nur mein Polygon neu zeichnen.

Weiß da jemand wie man das am besten löst?

Liebe Grüße
 

Aldimann

Bekanntes Mitglied
Stell mal bitte ein kures Selbstkompilierbares Beispiel ein und erklär mal bitte genauer wann und warum sich dieses Polygon ändern kann.

Ich schau den Code nachher mal an und schaue was sich da machen ließe...

Gruß
 

Rainbow

Bekanntes Mitglied
...das Polygon kann die Farbe ändern, weil ich das so haben möchte
ist ein Zustand 1 soll es schwarz sein, bei 2 eben rot...keine ahnung, das ist ja auch trivial

und mit Hilfe von redraw()wollte ich dann gern dieses Polygon neu zeichnen, es gibt aber kein passendes redraw

Java:
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class DrawPolygon {
    private int state = 0;
    
    public DrawPolygon() {
        final Display display = Display.getDefault();
        final Shell shell = new Shell(display);
        
        shell.setText("Test");
        shell.setMinimumSize(500, 500);
        
        shell.addPaintListener(new PaintListener() {
            
            @Override
            public void paintControl(PaintEvent e) {
                GC gc = e.gc;
                gc.setAntialias(SWT.ON);
                
                int[] pointArray = {10, 10, 20, 10, 30, 30, 20, 30};
                
                if(state == 0)
                    gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
                else
                    gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
                gc.fillPolygon(pointArray);
            }
        });
        
        shell.addControlListener(new ControlListener() {
            
            @Override
            public void controlResized(ControlEvent e) {
                state = 1;
                if(!shell.isDisposed()) shell.redraw(0, 0, 100, 100, false);
            }
            
            @Override
            public void controlMoved(ControlEvent e) {
                state = 0;
                if(!shell.isDisposed()) shell.redraw(0, 0, 100, 100, false);
            }
        });
        
        shell.pack();
        shell.open();
        
        while(!shell.isDisposed()) {
            if(!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
    }
    
    public static void main(String[] args) {
        new DrawPolygon();
    }
    
}
 

Rainbow

Bekanntes Mitglied
das mit dem No more handles hatte sich erledigt, ich will dennoch wissen, wie man ein Polygon neu zeichnen kann
ob so was überhaupt möglich ist
 

Aldimann

Bekanntes Mitglied
Das einzige was mir da spontan einfällt ist
Java:
gc.dispose()
zu machen und danach das GC neu zu erzeugen und darauf dann wieder herum zu malen.

Ich hab es allerdings gerade nicht ausprobiert, jedoch werden nur so die Ressourcen wieder vergegeben...
 

Rainbow

Bekanntes Mitglied
das sachen die ich anlege disposed werden müssen ist mir doch klar
darum gehts ja auch nicht

ich möchte einfach nur ein redraw machen und das für einen bestimmten ausschnitt
das ganze gc zu disposen ist nicht mein ziel

wenn das keinen sinn ergibt fragt man sich doch, warum existiert eine Methode redraw(x,y,width,height, boolean)?
 

Aldimann

Bekanntes Mitglied
Also ich seh bei org.eclipse.swt.graphics.GC kein redraw und hab mir grad die 3.6.1 von SWT gezogen...


Und das redraw auf der shell ist schlicht dafür da wenn sich elemente geändert haben dies auch anzuzeigen.

Hab ich also zur Laufzeit ein Textfeld hinzugefügt muss ich redraw aufrufen...

Wie willst du denn dem Polygon mitteilen, dass es sich zu ändern hat? Geht ja gar nicht, denn du hast es nicht als Objekt vorliegen sondern nur das GC und dem ist es vollkommen Wurscht was du da malst.

Um also das alte Polygon zu entfernen musst du gc.dispose() machen um dann GC neu zu erzeugen und damit wieder ein neues Polygon in neuer Farbe zu erstellen. Danach rufst du auf die überliegende Componente z.B. hier die Shell das redraw auf, damit die Änderung angezeigt wird.

Redraw ist in dem Fall nichts anderes als ein Aktualisieren
 
Zuletzt bearbeitet:

Rainbow

Bekanntes Mitglied
wie ich erfahre, ob sich was geändert hat geht klar und deutlich aus dem beispiel hervor
wofür das redraw da ist weiß ich

es ging wie gesagt darum, ums noch einmal zu sagen, ob ich auch bestimmte bereiche aktualisieren kann, bei denen es sich nicht um das ganze fenster oder ein Rechteck handelt. Denn diese Funktionalität ist bereits gegeben.

Das ich ein dispose aufrufen muss, ist völlig logisch...alles dinge die ich bereits wusste
 

Sonecc

Gesperrter Benutzer
Gut, dann weißt du nämlich auch die Antwort auf deine Frage, willst sie aber nicht wahrhaben...
Entweder du malst drüber oder du disposed, ob du das nun tun willst oder nicht ist dem GC egal.
 

Rainbow

Bekanntes Mitglied
schon mal gelesen was du zitiert hast?

...ich schreib ich weiß wofür das da ist und du schreibst ich soll die api lesen wenn cih wissen will wofürs da ist....

wer lesen kann ist halt doch klar im vorteil ;)
 
G

Gast2

Gast
Also hier mal was sinnvolles mach es so dann tuts...
Java:
        shell.addPaintListener(new PaintListener() {
            private GC gc;
            @Override
            public void paintControl(PaintEvent e) {
            	if(gc != null){
            		gc.dispose();
            	}
                gc = e.gc;
                gc.setAntialias(SWT.ON);
                
                int[] pointArray = {10, 10, 20, 10, 30, 30, 20, 30};
                
                if(state == 0)
                    gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
                else
                    gc.setBackground(display.getSystemColor(SWT.COLOR_RED));
                gc.fillPolygon(pointArray);
            }
        });
 

Neue Themen


Oben