Как сделать так, чтобы метка наследовала сборщик мусора Composite в SWT

Я пишу приложение, и наши дизайнеры хотят использовать градиенты для некоторых фонов некоторых из наших композитов.

Я написал следующий код:

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);

        }
    });

Это хорошо рисует градиент на композите, но у нас есть Label / CLabels, Canvases и Links поверх композита.

В этих областях фон просто серый, который вы получаете при рисовании пустого холста.

Я пытался заставить метки наследовать фон следующим образом:

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

Но это оставляет меня с тем же серым цветом по умолчанию и без градиента за компонентами поверх Composite.

Есть ли предложения по использованию градиента в качестве фона для каждого элемента?

Я бы не возражал против рисования градиента на gc с предоставленным изображением, а затем установки фона для этого изображения. Однако этот метод вообще не работал, ни составной, ни какой-либо из его элементов.

Также я не могу установить градиент индивидуально, насколько мне известно. Мы хотим, чтобы вся композиция представляла собой единый плавный градиент.

[править] Я загрузил пример на twitpic здесь.

Спасибо,

Брайан Джанфоркаро

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
8
0
7 300
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Первое, что я бы попробовал, - это захватить изображение из виджета и нарисовать часть изображения, где дочерний виджет расположен непосредственно на дочернем виджете.

Если это не сработает, попробуйте использовать один и тот же прослушиватель рисования для обоих виджетов, но перед тем, как установить преобразование GC после преобразования GC для перевода координат в координатное пространство метки:

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);

Кроме того, будьте осторожны, чтобы удалить все созданные вами экземпляры Color после того, как вы закончите с ними. В противном случае у вас будет утечка системных ресурсов, и в конечном итоге они закончатся.

Это была хорошая идея, но она основана на фактическом gc элемента управления, поэтому любой текст или что-либо в элементе управления будет стерто.

Brian Gianforcaro 27.09.2008 02:24
Ответ принят как подходящий

Используйте композитный.setBackgroundMode (SWT.INHERIT_DEFAULT), но не раскрашивайте композит напрямую - нарисуйте изображение и установите его в качестве фонового изображения с помощью композитный.setBackgroundImage (Изображение). Если я не упускаю какой-то трюк, это означает, что вам нужно регенерировать изображение только при изменении размера композита.

Вы должны иметь возможность вырезать и вставить этот код, чтобы понять, что я имею в виду:

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();
        }
    }

}

С небольшими изменениями и подталкиванием это отлично сработало. Спасибо!

Brian Gianforcaro 27.09.2008 02:24

Нет необходимости устанавливать фоновое изображение. Меня тоже устраивает установка цвета.

Mot 08.06.2011 18:10

Другие вопросы по теме