Pregunta

Estoy escribiendo una aplicación y nuestros diseñadores quieren usar gradientes para algunos de los fondos en algunos de nuestros compuestos.

Escribí el siguiente código:

composite.addListener (SWT.Paint, new Listener () {
    public void handleEvent (Event e) {
            GC gc = e.gc;
            Rectangle rect = composite.getClientArea ();
            Color color1 = new Color (display, 0, 0, 0);
            Color color2 = new Color (display, 255, 255, 255);
            gc.setForeground(color1);
            gc.setBackground(color2);
            gc.fillGradientRectangle (rect.x, rect.y, rect.width, rect.height , true);

        }
    });

Esto dibuja la multa de degradado en el compuesto, pero tenemos etiquetas / CLabels, lienzos y enlaces en la parte superior del compuesto.

En estas áreas, el fondo es solo el gris liso que se obtiene al dibujar un lienzo vacío.

He intentado forzar las etiquetas para heredar el fondo de esta manera:

label.setBackgroundMode(SWT.INHERIT_DEFAULT) //SWT.INHERIT_FORCE Doesn't work either

Pero esto me deja con el mismo gris predeterminado y sin degradado detrás de los componentes en la parte superior del Compuesto.

¿Alguna sugerencia para que el gradiente sea el fondo de cada elemento?

No me opondría a dibujar el degradado en un gc con una imagen suministrada y luego establecer el fondo para esa imagen. Sin embargo, ese método simplemente no ha funcionado, ni compuesto ni ninguno de sus elementos.

Tampoco me es posible establecer el gradiente individualmente según mi conocimiento. Queremos que todo el compuesto sea un gradiente de flujo uniforme.

[editar] Subí un ejemplo hasta twitpic aquí .

Gracias,

Brian Gianforcaro

¿Fue útil?

Solución

Use composite.setBackgroundMode (SWT.INHERIT_DEFAULT) , pero no pinte el compuesto directamente: pinte una imagen y configúrela como la imagen de fondo usando composite.setBackgroundImage (Image) . A menos que me esté faltando un truco, esto significa que solo tienes que regenerar la imagen cuando el compuesto también se redimensiona.

Debes poder cortar y pegar este código tal como está para ver lo que quiero decir:

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

/**
 * SWT composite with transparent label
 * 
 * @author McDowell
 */
public class Sweet {

    private Image imageGradient;
    private Label label;
    private Composite composite;

    private void createComponents(Shell parent) {
        composite = new Composite(parent, SWT.NONE);
        composite.addListener(SWT.Resize, new Listener() {
            public void handleEvent(Event e) {
                changeImage();
            }
        });
        composite.setLayout(new FormLayout());
        composite.setBackgroundMode(SWT.INHERIT_DEFAULT);

        label = new Label(composite, SWT.None);
        label.setText("Hello, World!");
    }

    private void changeImage() {
        Image oldImage = imageGradient;

        Display display = composite.getDisplay();
        Rectangle rect = composite.getClientArea();
        imageGradient = new Image(display, rect.width, rect.height);
        GC gc = new GC(imageGradient);
        try {
            Color color1 = new Color(display, 200, 200, 255);
            try {
                Color color2 = new Color(display, 255, 255, 255);
                try {
                    gc.setForeground(color1);
                    gc.setBackground(color2);
                    gc.fillGradientRectangle(rect.x, rect.y, rect.width,
                            rect.height, true);
                } finally {
                    color2.dispose();
                }
            } finally {
                color1.dispose();
            }
        } finally {
            gc.dispose();
        }
        composite.setBackgroundImage(imageGradient);

        if (oldImage != null) {
            oldImage.dispose();
        }
    }

    private void openShell(Display display) {
        Shell shell = new Shell(display);
        try {
            shell.setSize(200, 100);
            shell.setLayout(new FillLayout());
            createComponents(shell);
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
        } finally {
            if (!shell.isDisposed()) {
                shell.dispose();
            }
        }
    }

    public void run() {
        Display display = Display.getDefault();
        try {
            openShell(display);
        } finally {
            display.dispose();
        }
    }

    public void dispose() {
        if (imageGradient != null) {
            imageGradient.dispose();
        }
    }

    public static void main(String[] args) {
        Sweet sweet = new Sweet();
        try {
            sweet.run();
        } finally {
            sweet.dispose();
        }
    }

}

Otros consejos

Lo primero que intentaría es captura una imagen desde el widget y pinta la parte de la imagen donde el widget secundario está ubicado directamente en el widget secundario.

Si eso no funciona, intente usar el mismo detector de pintura para ambos widgets, pero antes de configurar la transformación del GC en después de transformar el GC para traducir las coordenadas al espacio de coordenadas de la etiqueta:

Listener listener = new Listener () {
  public void handleEvent (Event e) {
    GC gc = e.gc;
    Rectangle rect = composite.getClientArea ();
    Point offset = ((Control)e.widget).toControl(composite.toDisplay(0, 0));
    Color color1 = new Color (display, 0, 0, 0);
    Color color2 = new Color (display, 255, 255, 255);
    gc.setForeground(color1);
    gc.setBackground(color2);
    gc.fillGradientRectangle (rect.x + offset.x, rect.y + offset.y,
        rect.width, rect.height , true);
  }
}
composite.addListener (SWT.Paint, listener);
label.addListener(SWT.Paint, listener);

Además, tenga cuidado de eliminar cualquier instancia de Color que cree después de que haya terminado con ellas. De lo contrario, perderá recursos del sistema y finalmente se agotará.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top