GXT3: Как реализовать кнопки SVG

Использование иконок SVG имеет много преимуществ по сравнению с иконками png/gif. В результате я хотел бы реализовать класс кнопки svg, который будет действовать как виджет gwt. Есть ли уже что-то существующее в GXT 3? Или какой будет лучший вариант для реализации такого виджета? Благодарю.


Больше деталей:

Мне нужен чистый кликабельный значок SVG, действующий как виджет кнопки. Он должен иметь обработчик щелчка мыши и возможность применять разные CSS в трех состояниях: нормальный, зависание, отключен. Я не хочу кнопку с иконкой svg внутри.

1 ответ

В браузерах, которые их поддерживают, SVG можно использовать так, как если бы это был файл изображения (png/jpg/etc). GXT/GWT не должно иметь никакого значения, вы просто должны применить изображение.

Вместо того, чтобы создавать свой собственный виджет (который, конечно, является опцией), вы можете использовать встроенные виджеты, которым можно сказать использовать любое изображение или класс CSS (в зависимости от виджета).

Например, GXT TextButton имеет setIcon метод, который принимает ImageResource, Как правило, они создаются в ClientBundle, но генерация кода для GWT ClientBundle не знает что такое SVG

ImageResource интерфейс имеет реализацию, встроенную в GWT, ImageResourcePrototype, что позволяет вам указать все необходимые параметры. Второй параметр - это URL, путь к изображению, который будет отображаться, пока браузер его поддерживает. Итак, нам нужно получить SVG-файл, который вы хотите использовать, в ImageResourcePrototype.

    ImageResource icon = new ImageResourcePrototype("icon", UriUtils.fromSafeConstant("/path/to/my.svg"), 0, 0, 20, 20, false, false);
    TextButton button = new TextButton("square", icon);
    RootPanel.get().add(button);

Теперь вы можете сделать это, просто передав нормальный URL, но тогда мы ничем не лучше обычного изображения, так как нам все еще нужно обратное путешествие к серверу - большинство значков имеют всего несколько килобайт, но накладные расходы HTTP-вызов может быть настолько плохим, что ваш SVG будет таким же плохим. К счастью, все встроенные ImageResources в GWT уже включены в приложение, поэтому HTTP-вызовы не требуются. Оказывается, мы также можем связать наш SVG-файл, хотя нам нужно, чтобы браузер справился с ним.

Поместите файл SVG в ваш исходный код вместе с Java, и мы сделаем из него пакет. Я положил эту очень скучную иконку в файл под названием icon.svg:

<svg width="50" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">

  <rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
</svg>

Далее используйте его в нашем приложении. Я сделал точку входа, которая просто берет этот значок и помещает его в кнопку. Мы используем DataResource здесь, чтобы обратиться к файлу как к URL-адресу данных внутри нашего приложения, но нам нужно правильно указать mime-тип, чтобы браузер понял, что это изображение:

public class SampleIconEntryPoint implements EntryPoint {
    interface Bundle extends ClientBundle {
        @Source("icon.svg")
        @MimeType("image/svg+xml")
        DataResource icon();
    }

    @Override
    public void onModuleLoad() {
        Bundle bundle = GWT.create(Bundle.class);
        ImageResource icon = new ImageResourcePrototype("icon", bundle.icon().getSafeUri(), 0, 0, 50, 50, false, false);
        TextButton button = new TextButton("square", icon);
        RootPanel.get().add(button);
    }
}

Оказанная кнопка со значком SVG


Это можно упростить, добавив поддержку файлов.svg в ImageResourceGenerator в GWT, но это оказывается не очень распространенным вариантом использования.


Итак, что SVG имеет над растровыми изображениями? Для больших изображений очень много! Они могут быть намного меньше для того же уровня детализации, так как они хорошо растягиваются, но для маленьких значков его можно ударить или пропустить. Легче изменить некоторые подробности о них на лету, но это действительно выходит за рамки вопроса, касающегося использования SVG в gwt (см. Библиотеку GXT Chart / Draw для множества простых инструментов визуализации SVG), и не часто вопрос для одного изображения на кнопке. Изображения значков имеют небольшой размер и сохраняют несколько байтов здесь, и, вероятно, неэффективное использование времени - плюс, SVG требует больше времени для рендеринга в браузере, чем гораздо более простые изображения (хотя, опять же, разница будет минимальной для очень маленьких браузеры).


Редактировать, пытаясь решить вопрос редактирования вместо исходной точки.

SVG-элементы - это почти обычные dom-элементы, но проверьте, какие браузеры вам нужно поддерживать, чтобы убедиться, что они будут работать правильно. https://developer.mozilla.org/en-US/docs/SVG_In_HTML_Introduction дает краткое представление о том, как нужно создавать элементы, чтобы исправить их пространство имен, чтобы браузер работал с ними корректно. Кроме того, они ведут себя примерно как обычные элементы DOM в GWT. Я бы вообще предложил вам относиться к ним как к обычным элементам dom в GWT, и поэтому ваш виджет не должен прикреплять обработчики к дочерним элементам, а просто использовать addDomHandler как обычно на каждом виджете. Учитывая способность элементов SVG перекрывать друг друга (в зависимости от порядка в DOM), вы могли бы рассмотреть другие способы увидеть, какой элемент находится над другими, если вам нужно точно знать, над чем находится мышь (хотя для кнопки, это не должно иметь значения).

Как упомянуто выше, инструменты рисования GXT предоставляют класс DrawComponent, который может использовать SVG и позволяет получать события, которые происходят с каждым нарисованным спрайтом, а также нормализовать для различных проблем браузера (поддержка Canvas, если это возможно, или VML, если необходимо).

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