Устали от ручного кодирования ваших пользовательских интерфейсов? Даже если вы используете конструктор GUI, вам все равно нужно обновлять компоненты пользовательского интерфейса при изменении модели. У Ричарда Кеннарда есть решение: метавиджет . Metawidget — это инструмент сопоставления объектного / пользовательского интерфейса и проект с открытым исходным кодом. Metawidget проверяет существующую серверную
архитектуру приложения и создает компоненты, встроенные в существующую интерфейсную среду. Здесь мы узнаем все подробности от самого Ричарда.
Привет, Ричард, сначала расскажи, пожалуйста, кто ты и чем занимаешься?
Я Ричард Кеннард и я независимый консультант по программному обеспечению. Я специализируюсь на разработке Java EE и работаю в экспертной группе JSR-299 (Web Beans). Я нахожусь в Сиднее, Австралия.
Что такое Metawidget и какую проблему он пытается решить?
Metawidget берет ваши существующие объекты домена и создает во время выполнения компоненты пользовательского интерфейса, встроенные в существующую
интерфейсную среду:
Разработка пользовательского интерфейса занимает очень много времени, поэтому любая автоматизация является настоящим благом. Но современные решения имеют тенденцию делать либо слишком мало, либо слишком много. Например, инструменты визуального компоновщика хороши, но вы все равно должны перетаскивать каждое поле и метку и переделывать свой пользовательский интерфейс при изменении внутреннего кода. Существуют и другие инструменты, которые пытаются автоматически сгенерировать весь пользовательский интерфейс, но в итоге они диктуют, как он выглядит, какую платформу он использует и т. Д.
Metawidget пытается найти «сладкую точку» автоматического создания пользовательского интерфейса: достаточно, чтобы быть полезным, а не слишком сильно, чтобы ограничивать вас. Вы просто даете ему свой существующий объект домена:
public class Person {
private String fullname = "Homer Simpson";
private int kids = 3;
private boolean retired = false;
public String getFullname() {
return this.fullname;
}
public void setFullname( String fullname ) {
this.fullname = fullname;
}
//...more getters and setters...
}
А Metawidget предоставляет вам компонент, готовый для вставки в существующий пользовательский интерфейс:
Как вы пришли к созданию этого проекта, можете ли вы вспомнить момент, когда вы впервые начали думать об этом?
Я помню первые релизы JPA. Я думал, что возможность аннотировать ваши доменные объекты вместо того, чтобы писать файлы сопоставления XML, была потрясающей — у нее был настоящий дух «Не повторяйся сам». Мы перешли от необходимости управлять дублирующими объявлениями полей в 3 местах (схема базы данных, операторы SQL, объекты домена), всего лишь в 2 местах (объекты вашего домена и файл сопоставления XML), и только в 1 место (аннотированный объект домена). Я думал, что это было здорово.
Но потом я обернулся и все еще должен был набрать <input type = «text» name = «company»>. Это заставило меня задуматься: «Почему интерфейс особенный? Почему я все еще должен управлять дубликатами объявлений полей в своем слое пользовательского интерфейса?
Поэтому я создал автоматически генерируемый компонент Java Server Faces. Я использовал и усовершенствовал его в течение нескольких лет, и это помогло сэкономить время. Затем я расширил его, чтобы поддерживать несколько интерфейсных сред (Swing, Spring, Struts, Android) и несколько серверных частей, и он стал Metawidget.
Можете ли вы описать различные сценарии, в которых Metawidget может быть полезен?
Если у вас есть приложение с несколькими экранами ввода, Metawidget может сэкономить вам огромное количество времени и кода. И когда вы позже добавите и реорганизуете поля, Metawidget автоматически переделает ваш интерфейс. И если вам нужно поддерживать несколько интерфейсов для одного и того же проекта (рабочий стол, веб, мобильный), Metawidget поддерживает их синхронизацию для вас.
At the time of writing, Metawidget supports the following front-ends: Android, Java Server Faces (including JBoss RichFaces),
Java Server Pages, Spring Web MVC, Struts, and Swing (including Beans Binding). On the back-end, Metawidget supports Annotations, Hibernate, Hibernate Validator, JavaBeans, and Java Persistence Architecture. And the architecture is designed to encourage people to plug in more!
Can you walk us through an example of how Metawidget integrates with an existing framework, such as Beans Binding?
Metawidget
‘drops in’ to your existing environment and uses whatever is
available. In itself it doesn’t have any JAR dependencies —
instead it leverages as many frameworks as it finds.
So
if you have Swing on the front-end, Metawidget will create
JComponents. And if you
have Hibernate Validator on the back-end, Metawidget will inspect its
annotations for useful UI hints (eg. @Min
and @Max for a JSlider).
And so on.
If
Beans Binding is available, Metawidget will automatically wire up its
JComponents to the
back-end. You just tell Metawidget what object to inspect:
public class Main {
public static void main( String[] args ) {
SwingMetawidget metawidget = new SwingMetawidget();
metawidget.setInspector( new JavaBeanInspector() );
metawidget.setBindingClass( BeansBinding.class );
metawidget.setToInspect( new Person() );
//...add the metawidget to a JFrame...
}
}
And
Metawidget does the rest:
To
save the data back, you just do:
.add( new JButton( new AbstractAction( "Save" ) {
public void actionPerformed( ActionEvent e ) {
metawidget.save();
}
} )
Or
you can use the full range of Beans Binding sync’ing options.
I’ve
posted the complete code to this example on my blog, in an entry entitled Beans Binding and Metawidget.
Are there any disadvantages to automatic UI generation?
I think the disadvantages come in two forms.
One is when automatic UI generation goes ‘too far’, in other words, when it starts
dictating what your screens look like, or how the user navigates between
them, or what UI framework they use. Metawidget doesn’t do this. It
creates only parts of a screen, not the whole thing. And it creates
native components and gives you direct access to them. For example, with
SwingMetawidget you can just do…
JTextField field = (JTextField) metawidget.getComponent( 1 );
…and you’re right there in the Swing API with all its capabilities. So
Metawidget doesn’t constrain you.
The other disadvantage is when automatic generation doesn’t go ‘far
enough’: some approaches require you redefine your business objects in
their own framework-specific format or use their own framework-specific
tools. Again, Metawidget doesn’t do this. It reuses your existing
business objects, and emphasizes Metawidget finding information out for
itself (via its Inspectors) rather than you having to supply it with
information.
So when would one not want to use this approach?
Building great UIs is both art and science. Metawidget doesn’t attempt
to address the art, it only automates the science.
That is, it doesn’t overlap with those areas of UI design involving
creativity and subjectivity — so you shouldn’t use it there.
Metawidget’s goal is only to ease the creation of those areas that are
already rigidly defined. Typically, this means areas that display data
and those that collect data: these tend to be both common place and
consistent (indeed, consistency is a desirable trait) so there is good
opportunity for automation in these areas.
A new release of Metawidget was recently announced. Can you say something about
it?
I’m
very much in the ‘release early, release often’ phase right now. I
want to encourage as much feedback as I can to make the 1.0 release
as strong as possible.
This
latest release adds Hibernate support (it scans your mapping files
for useful UI hints, like not-null),
upgrades the Android support (Google recently released an upgraded
SDK), adds fuller support for Java types (byte/Byte,
short/Short,
etc.) and general bug fixes and additional unit tests.
Do you
work on this project alone? What’s the community like around
Metawidget?
At
the moment Metawidget is just me. But the design is very modular so
I’m hoping to attract others to the cause ?
For
example, if you’ve written a UI framework/component library/layout
manager, you can make it easier for people to adopt by writing a
Metawidget for it. Or if you’ve got a
validation/persistence/rule-based framework, you can make it easier
for people to plug in to their front-end by writing an Inspector for
it.
What does
the future direction of the project look like? What can we expect in
the coming months/years?
My
immediate focus is to establish the list of features people want to
see in a 1.0 release, then solidify support for them.
The
longer term goal is to save everybody a lot of time: to find the
‘sweet spot’ of automatic UI generation that makes it useful enough
and flexible enough to become a regular part of everyday Java
development.