Category: API

JVx Reference, Custom Components

Post to Twitter

Let's talk about custom components, and how to create them.

The GUI of JVx

We've previously covered how the GUI of JVx works, and now we will have a look on how we can add custom components to the GUI.

In the terminology of JVx there are two different kinds of custom components:

  1. UI based
  2. Technology based

We will look at both, of course.

Custom components at the UI layer

The simplest way to create custom components is to extend and use already existing UI classes, like UIPanel or UIComponent. These custom components will be Technology independent because they use Technology independent components, there is no need to know about the underlying Technology. You can think of those as a "remix" of already existing components.

The upside is that you never have to deal with the underlying Technology, the downside is that you can only use already existing components (custom drawing is not possible, for example).

Let's look at a very simple example, we will extend the UILabel to always display a certain postfix along with the set text:

public class PostfixedLabel extends UILabel
{
    private String postfix = null;

    // We must store the original text so that we can return
    // it if requested. Otherwise we could only return the text
    // with the appended postfix, which works unless the postfix
    // changes.
    private String text = null;

    public PostfixedLabel()
    {
        super();
    }

    public PostfixedLabel(String pText)
    {
        super(pText);
    }

    public PostfixedLabel(String pText, String pPostfix)
    {
        super(pText);

        setPostfix(pPostfix);
    }

    @Override
    public String getText()
    {
        return text;
    }

    @Override
    public void setText(String pText)
    {
        text = pText;

        if (!StringUtil.isEmpty(postfix) && !StringUtil.isEmpty(pText))
        {
            // We translate the text and the postfix now separately,
            // the underlying label will obviously try to translate
            // the concatenated version.
            super.setText(translate(pText) + translate(postfix));
        }
        else
        {
            super.setText(pText);
        }
    }

    public String getPostfix()
    {
        return postfix;
    }

    public void setPostfix(String pPostfix)
    {
        postfix = pPostfix;

        // If the postfix changed, we must update the text.
        setText(text);
    }
}

It will be treated just like another label, but every time a text is set, the postfix is appended to it.

Another example, we want a special type of component, one that always does the same but will be used in many different areas of the application, it should contain a label and two buttons. The best approach for a custom component which should not inherit any specific behavior is to extend UIComponent:

public class BeepComponent extends UIComponent<UIPanel>
{
   public BeepComponent()
   {
       super(new UIPanel());
       
       UIButton highBeepButton = new UIButton("High Beep");
       highBeepButton.eventAction().addListener(Beeper::playHighBeep);
       
       UIButton lowBeepButton = new UIButton("Low Beep");
       highBeepButton.eventAction().addListener(Beeper::playLowBeep);
       
       UIFormLayout layout = new UIFormLayout();        

       uiResource.setLayout(layout);
       uiResource.add(new UILabel("Press for beeping..."), layout.getConstraints(0, 0, -1, 0));
       uiResource.add(highBeepButton, layout.getConstraints(0, 1));
       uiResource.add(lowBeepButton, layout.getConstraints(1, 1));
   }
}

So we extend UIComponent and set a new UIPanel as UIResource on it, which we can use later and which is the base for our new component. After that we added a label and two buttons which will play beep sounds if pressed. This component does not expose any specific behavior as it extends UIComponent, it only inherits the most basic properties, like background color and font settings, yet it can easily be placed anywhere in the application and will perform its duty.

Custom controls at the Technology layer

The more complex option is to create a custom component at the Technology layer. That means that we have to go through a multiple steps process to create and use the component:

  1. Create an interface for the functionality you'd like to expose
  2. Extend the Technology component (if needed)
  3. Implement the necessary interfaces for JVx
  4. Extend the factory to return the new component
  5. Create a UIComponent for the new component
  6. Use the new factory

I will walk you through this process, step by step.

The upside is that we can use any component which is available to us in the Technology, the downside is that it is quite some work to build the correct chain, ideally for every technology.

Creating an interface

The first step is to think about what functionality the component should expose, we will use a progress bar as example. We don't want anything fancy for now, a simple progress bar on which we set a percent value should be more than enough:

/**
 * The platform and technology independent definition for a progress bar.
 */

public interface IProgressBar extends IComponent
{
    /**
     * Gets the current value, in percent.
     *
     * @return the current value. Should be between {@code 0} and {@code 100}.
     */

    public int getValue();
   
    /**
     * Sets the current value, in percent.
     *
     * @param pValue the value. Should be between {@code 0} and {@code 100}.
     */

    public void setValue(int pValue);
}

Might not be the most sophisticated example (especially in regards to documentation) but it will do for now. This interface will be the foundation for our custom component.

Extending the component, if needed

We will be using Swing and the JProgressBar for this example, so the next step is to check if we must add additional functionality to the Technology component. In our case we don't, as we do not demand any behavior that is not provided by JProgressBar, but for the sake of the tutorial we will still create an extension on top of JProgressBar anyway.

public class ExtendedProgressBar extends JProgressBar
{
    public ExtendedProgressBar(int pMin, int pMax)
    {
        super(pMin, pMax);
    }
}

Within this class we could now implement additional behavior independent of JVx. For example, we provide many extended components for Swing, JavaFX and Vaadin with additional features but without depending on JVx. The extension layer is the perfect place to extend already existing components with functionality which will be used by, but is not depending on, JVx.

Creating the Implementation

The next step is to create an Implementation class which allows us to bind our newly extended JProgressBar to the JVx interfaces. Luckily there is the complete Swing Implementation infrastructure which we can use:

public class SwingProgressBar extends SwingComponent<ExtendedProgressBar>
                              implements IProgressBar
{
    public SwingProgressBar()
    {
        // We can hardcode the min and max values here, because
        // we do not support anything else.
        super(new ExtendedProgressBar(0, 100));
    }
   
    @Override
    public int getValue()
    {
        return resource.getValue();
    }
   
    @Override
    public void setValue(int pValue)
    {
        resource.setValue(pValue);
    }
}

That's it already. Again, in this case it is quite simple because we do not expect a lot of behavior. The implementation layer is the place to "glue" the component to the JVx interface, implementing missing functionality which is depending on JVx and "translating" and forwarding values and properties.

Extending the factory

Now we must extend the Factory to be aware of our new custom component, that is equally simple as our previous steps. First we extend the interface:

public interface IProgressBarFactory extends IFactory
{
    public IProgressBar createProgressBar();
}

And afterwards we extend the SwingFactory:

public class ProgressBarSwingFactory extends SwingFactory
                                     implements IProgressBarFactory
{
    @Override
    public IProgressBar createProgressBar()
    {
        SwingProgressBar progressBar = new SwingProgressBar();
        progressBar.setFactory(this);
        return progressBar;
    }
}

Again, it is that easy.

Creating the UIComponent

So that we can use our new and shiny progress bar easily, and without having to call the factory directly, we wrap it one last time in a new UIComponent:

public class UIProgressBar extends UIComponent<IProgressBar>
                           implements IProgressBar
{
    public UIProgressBar()
    {
        // We'll assume that, whoever uses this component,
        // is also using the correct factory.
        super(((IProgressBarFactory)UIFactoryManager.getFactory()).createProgressBar());
    }
   
    @Override
    public int getValue()
    {
        return uiResource.getValue();
    }
   
    @Override
    public void setValue(int pValue)
    {
        uiResource.setValue(pValue);
    }
}

Nearly done, we can nearly use our new and shiny component in our project.

Using thecustom factory

Of course we have to tell JVx that we want to use our factory, and not the default one. Depending on the technology which is used, this has to be done at different places:

Swing and JavaFX

Add the factory setting to the application.xml of the application:

<Launcher.uifactory>your.package.with.custom.components.SwingProgressBarFactory</Launcher.uifactory>
Vaadin

Add the following setting to the web.xml under the WebUI Servlet configuration:

<init-param>
    <param-name>Launcher.uifactory</param-name>
    <param-value>your.package.with.custom.components.VaadinProgressBarFactory</param-value>
</init-param>

Using our new component

And now we are done, from here we can use our custom component like any other.

UIProgressBar progressBar = new UIProgressBar();
progressBar.setValue(65);

// Skip

add(progressBar, constraints);

Wrapping custom components with UICustomComponent

There is a third way to have Technology dependent custom components in JVx, you can wrap them within a UICustomComponent:

JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setValue(100);

UICustomComponent customProgressBar = new UICustomComponent(progressBar);

// Skip

add(customProgressBar, constraints);

This has the upside of being fast and easy, but the downside is that your code has to know about the currently used Technology and is not easily portable anymore.

Conclusion

As you can see, there are multiple ways of extending the default set of components which are provided by JVx, depending on the use case and what custom components are required. It is very easy to extend JVx with all the components one does require.

JVx Reference, of Technologies and Factories

Post to Twitter

Let's talk about the UI layer, the implementations and the factory that powers it all.

The basics

For everyone who does not know, JVx allows you to write code once and run it on different GUI frameworks, without changing your code. This is achieved by hiding the concrete GUI implementations behind our own classes, the UI classes, and providing "bindings" for different GUI frameworks behind the scenes. Such a "Single Sourcing" approach has many advantages, and just one of them is that migrating to a new GUI framework requires only the change of a single line, the one which controls which factory is created.

The Factory Pattern

The Factory Pattern is an important pattern in Object-Oriented-Programming, it empowers us to delegate the creation of Objects to another Object which must not be known at design and/or compile time. That allows us to use Objects which have not been created by us but merely "provided" to us by an, for us unknown, implementation.

Like an onion

JVx is separated into different layers, with the UI layer being at the top and of the most concern to users.

JVx Layers

Technology

Obviously, the first one in the chain is the so called "technology" layer. It represents the UI technology, for example Swing, JavaFX or Vaadin, which is used to power the JVx application.

To put it into a more simple term:

public class JButton {}

Extension

Next comes the extension layer, components from the technology are extended to support needed features of JVx. This includes creating bindings for the databook, additional style options and changing of behavior if necessary. From time to time this also includes creating components from scratch if the provided ones do not meet the needs or there simply are none with the required functionality. For the most part, we do our best that these layers can be used without JVx, meaning that they represent a solitary extension to the technology. A very good example is our JavaFX implementation, which compiles into two separate jars, the first being the complete JVx/JavaFX stack, the second being stand-alone JavaFX extensions which can be used in any application and without JVx.

Theoretically one can skip this layer and directly jump to the Implementation layer, but so far it has proven necessary (for cleanliness of the code and object structure and sanity reasons) to create a separate extension layer.

public class JExtendedButton extends JButton {}

Implementation

After that comes the implementation layer. The extended components are extended to implement JVx interfaces. This is some sort of "glue" layer, it binds the technology or extended components against the interfaces which are provided by JVx.

public class SwingButton<JExtendedButton> implements IButton {}

UI

Last but for sure not least is the UI layer, which wraps the implementations. It is completely Implementation independent, that means that one can swap out the stack underneath:

JVx Layers

This is achieved because the UI layer is not extending the Implementation layer, but wrapping instances provided by the factory. It is oblivious to what Technology is actually underneath it.

public class UIButton<IButton> implements IButton {}

SwingButton resource = SwingFactory.createButton()

Why is the UI layer necessary?

It isn't, not at all. The Implementations could be used directly without any problems, but having yet another layer has two key benefits:

  1. It allows easier usage.
  2. It allows to add Technology independent features.

By wrapping it one more time we gain a lot of freedom which we would not have otherwise, when it comes to features as when it comes to coding. The user does not need to call the factory directly and instead just needs to create a new object:

IButton button = new UIButton();

Internally, of course, the Factory is called and an implementation instance is created, but that is an implementation detail. If we would use the implementation layer directly, our code would either need to know about the implementations, which doesn't follow the Single-Sourcing principle:

IButton button = new SwingButton();

It also would be possible to directly use the factory (but this isn't modern coding style):

IButton button = UIFactoryManager.getFactory().createButton();

Both can be avoided by using another layer which does the factory calls for us:

public class UIButton implements IButton
{
    private IButton resource;

    public UIButton()
    {
        resource = UIFactoryManager.getFactory().createButton();
    }

    public void someInterfaceMethod()
    {
        resource.someInterfaceMethod();
    }
}

Additionally this layer allows us to implement features which can be technology independent, our naming scheme, which we created during stress testing of an Vaadin application, is a very good example of that. The names of the components are derived in the UI layer without any knowledge of the underlying Technology or Implementation.

Also it does provide us (and everyone else of course) with a layer which allows to rapidly and easily build compound components out of already existing ones, like this:

public class LabeledButton extends UIPanel
{
    private IButton button = null;
    private ILabel label = null;
   
    public LabeledButton ()
    {
        super();

        initializeUI();
    }

    private void initializeUI()
    {
        button = new UIButton();
        label = new UILabel();
       
        setLayout(new UIBorderLayout());
        add(label, UIBorderLayout.LEFT);
        add(button, UIBorderLayout.CENTER);
    }
}

Of course that is not even close to sophisticated, or a good example for that matter. But it shows that one can build new components out of already existing ones without having to deal with the Technology or Implementation at all, creating truly cross-technology controls.

The Factory

The heart piece of the UI layer is the Factory, which is creating the Implemented classes. It's a rather simple system, a Singleton which is set at the beginning to the Technology specific factory which can be retrieved later:

// At the start of the application.
UIFactoryManager.setFactoryInstance(new SwingFactory());
// Or alternately:
UIFactory.getFactoryInstance(SwingFactory.class());

// Later inside the UI wrappers.
IButton button = UIFactory.getFactory().createButton();

The complexity of the implementation of the factory is technology dependent, but for the most part it is devoid of any logic:

public class SwingFactory implements IFactory
{
    @Override
    public IButton createButton()
    {
        SwingButton button = new SwingButton();
        button.setFactory(this);

        return button;
    }
}

It "just returns new objects" from the implementation layer. That's about it when it comes to the factory, it is as simple as that.

Piecing it together

With all this in mind, we know now that JVx has swappable implementations underneath its UI layer for each technology it utilizes:

JVx Layers

Changing between them can be as easy as setting a different factory. I say "can", because that is only true for Swing, JavaFX and similar technologies, Vaadin, obviously, requires some more setup work. I mean, theoretically one could embed a complete application server and launch it when the factory for Vaadin is created, allowing the application to be basically stand-alone and be started as easily as a Swing application. That is possible.

What else?

That is how JVx works in regards to the UI layer. It depends on "technology specific stacks" which can be swapped out and implemented for pretty much every GUI framework out there. We currently provide support for Swing, JavaFX and Vaadin, but we also had implementations for GWT and Qt. Additionally we do support a "headless" implementation which allows to use lightweight objects which might be serialized and send over the wire without much effort.

Adding a new Technology

Adding support for a new Technology is as straightforward as one can imagine, simply creating the Extensions/Implementations layers and implementing the factory for that Technology. Giving a complete manual would be out for scope for this post, but the most simple approach to adding a new stack to JVx is to start with stubbing out the IFactory and implementing IWindow. Once that one window shows up, it's just implementing one interface after another in a quite straightforward manner. And in the end, your application can switch to yet another GUI framework without the need to change your code.

JVx Reference, Events

Post to Twitter

Let's talk about events and event handling in JVx.

What are events...

Events are an important mechanism no matter to what programming language or framework you turn to. It allows us to react on certain actions and "defer" actions until something triggered them. Such triggers can be anything, like a certain condition is hit in another thread, the user clicked a button or another action has finally finished. Long story short, you get notified that something happened, and that you can now do something.

...and why do I need to handle them?

Well, you can't skip events, they are a cornerstone of JVx. Theoretically, you could use JVx without using any of its events, but you would not only miss out on a lot of functionality but also be unable to do anything useful. But don't worry, understanding the event system is easy, using it even easier.

Terminology

For JVx the following terminology applies: An event is a property of an object, you can register listeners on that event which will get invoked if the event is dispatched (fired). Every event consists of the EventHandler class which allows to register, remove and manage the listeners and also dispatches the events, meaning invoking the listeners and notifying them that the event occurred. There is no single underlying listener interface.

Within the JVx framework, every event-property of an object does start with the prefix "event" to make it easily searchable and identifiable. But enough dry talk, let's get started.

Attaching listeners as class

The easiest way to get notified of events is to attach a class (which is implementing the listener interface) to an event as listener, like this:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener(new ActionListener());
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
}

private static final class ActionListener implements IActionListener
{
    public void action(UIActionEvent pActionEvent) throws Throwable
    {
        System.out.println("Button clicked!");
    }
}

Attaching listeners as inlined class

Of course we can inline this listener class:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener(new IActionListener()
        {
            public void action(UIActionEvent pActionEvent) throws Throwable
            {
                System.out.println("Button clicked!");
            }
        });
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
}

Attaching listeners JVx style

So far, so normal. But in JVx we have support to attach listeners based on reflection, like this:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener(this, "doButtonClick");
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
   
    public void doButtonClick(UIActionEvent pActionEvent) throws Throwable
    {
        System.out.println("Button clicked");
    }
}

What is happening here is that, internally, a listener is created which references the given object and the named method. This allows to easily add and remove listeners from events and keeping the classes clean by allowing to have all related event listeners in one place and without additional class definitions.

Attaching listeners as lambdas

Yet there is more, we can of course attach lambdas to the events as listeners, too:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener((pActionEvent) -> System.out.println("Button clicked"));
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
}

Attaching listeners as method references

And last but not least, thanks to the new capabilities of Java 1.8, we can also use method references:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener(this::doButtonClick);
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
   
    private void doButtonClick(UIActionEvent pActionEvent) throws Throwable
    {
        System.out.println("Button clicked");
    }
}

Parameters or no parameters? To throw or not to throw?

By default we actually support two different classes of listeners, the specified event/listener interface itself, and (javax.rad.util.)IRunnable. Which means that you can also attach methods which do not have any parameters, like this:

public class MainFrame extends UIFrame
{
    public MainFrame()
    {
        super();
       
        UIButton button = new UIButton("Click me!");
        button.eventAction().addListener(this::doButtonClickNoParameters);
        button.eventAction().addListener(this::doButtonClickWithParameters);
       
        setLayout(new UIBorderLayout());
        add(button, UIBorderLayout.CENTER);
    }
   
    private void doButtonClickNoParameters() throws Throwable
    {
        System.out.println("Button clicked");
    }

    private void doButtonClickWithParameters(UIActionEvent pActionEvent) throws Throwable
    {
        System.out.println("Button clicked");
    }
}

Additionally, all listeners and IRunnable itself do support to throw Throwable, which is then handled inside the EventHandler. So you are very flexible when it comes to what methods you can attach and use as listeners.

Creating your own events

You can, of course, create your own EventHandlers and listeners to create your own events. All you need are two classes, an extension of EventHandler and a listener interface.

public class CustomEvent extends EventHandler
{
    public CustomEvent()
    {
        super(ICustomListener.class);
    }
}

public interface ICustomListener
{
    public void somethingHappened(String pName);
}

And that's it, from here on you can use it:

CustomEvent event = new CustomEvent();
event.addListener((pName) -> System.out.println(pName + " 1"));
event.addListener((pName) -> System.out.println(pName + " 2"));
event.addListener((pName) -> System.out.println(pName + " 3"));

event.dispatchEvent("Adam");

More methods!

You can also use an interface for listeners which has multiple methods, specifying in the constructor which method to invoke:

public class CustomEvent extends EventHandler
{
    public CustomEvent()
    {
        super(ICustomListener.class, "somethingOtherHappened");
    }
}

public interface ICustomListener
{
    public void somethingHappened(String pName);
    public void somethingOtherHappened(String pName, BigDecimal pValue);
    public void nothingHappened();
}

Now every time the event is dispatched, the somethingOtherHappened method will be invoked. Anyway, don't use this. The upside of having a "simple" listener interface with just one method (SAM-type) is that it allows to use lambdas with it. A listener interface with multiple methods won't allow this.

In JVx we reduced our listener interfaces to just one method (in a backward compatible way) to make sure all events can be used with lambdas.

Fire away!

That's it for this short reference sheet, that is how our event system can and should be used. Of course, there is much more to it under the hood, for example listeners being wrapped in proxy classes, reflection used for invoking methods and some more stuff. If you feel adventurous, be my guest and have a good look at the internals of EventHandler, it is quite an interesting read.

JVx SwingUI extensions

Post to Twitter

JVx defines a technology independent User Interface, with Interfaces. Each technology has to implement this interfaces for its components and controls, to be compatible with JVx. We have implemented all this interfaces for Swing.

In addition we have created some swing components with special features for business applications. This components are simple extensions to existing swing components and are supported from any Look and Feel. They can be used in any swing application with or without the whole JVx framework.

We will show here some of this components:

  • DesktopPane with tab or frame mode

    Switch between tab and frame view, Closable tabs (works with java 1.5 and is LaF independent), Drag and Drop Tabs, Tab navigation with keyboard, Modal frames, Background image.

    Frames

    Frame mode

    Tab mode

    Tab mode

    Desktop Background

    Desktop Background

  • ComboBoxes with user-defined popup components

    A base implementation of a ComboBox called ComboBase. With this combo you can build your own ComboBox for e.g. input first and last name in separate fields. We implemented a date chooser and a table selector (header is:

    Date Combo

    Date Combo

    Table Combo

    Table Combo

  • Table with load-on-demand model and ready-to-use cell editors/renderers

    A table which uses an IDataBook implementation as model (e.g. MemDataBook) and shows cell editors and renderers dependent of the cell data types, e.g. a table with image renderer and multiple choice editor/renderer

    Table with renderer and editor

    Table with renderer and editor

    Following editors/renderer are available: Text, Number (only numbers are allowed), Date, Multiple Choice, Image
  • Button

    A standard button and a toggle button with support for mouse-over borders.

  • Icon

    A special icon which supports image stretching and alignment.


Our implementation includes not only Swing components. It also contains some useful layouts:

  • FormLayout

    Anchor based layouting. Supports margins, stretching, gaps, ... It is designed for simple and complex forms.

  • BorderLayout

    Supports margins.

  • SequenceLayout

    Supports component stretching, component orientation, intelligent wrapping.

If you are interested in JVx, leave a comment or join our community.
You are welcome!

JVx 0.8 Beta 2 is verfügbar

Post to Twitter

Seit wenigen Minuten steht die 2. Beta Version von JVx 0.8 zum Download bereit. Die Änderungsliste ist diesmal etwas kürzer ausgefallen, doch unter der Haube wurde kräftig geschraubt.

Diese Version enthält vor allem im Hinblick auf das kommende WebUI einiges an Erweiterungen. Doch nähere Details dazu in einem der kommenden Posts

Was kann man von der Beta 2 erwarten?

  • Erhöhte Sicherheit

    Die Session steuert ab sofort den Zugriff auf Lifecycle Objekte und delegiert dies an den Security Managers. Sollten spezielle Zugrifssbeschränkungen existieren, wird der Zugriff nicht eingeschränkt.

    Weiters ist die Passwort Verschlüsselung nun konfigurierbar, wahlweise MD5, SHA 512 oder eine Standard Java Security konforme Implementierung.

  • Neue Utility Klassen (com.sibvisions.util)

    Siehe Javadoc

  • Performance Optimierung

    Durch die Vermeidung von Instanz Erzeugung beim Zugriff auf die Datenbank und bei der Behandlung der Metadaten wird einerseits Speicher und andererseits Zeit eingespart. Abhängig von der Anzahl der Datensätze ist der Unterschied deutlich merkbar.

  • Bugfixing

    Datenbanzugriff mit HyperSQL und Oracle, Bildbibliothek laden aus unterschiedlichen Threads, Serialisierung, Layouting, XML Security Manager uvm.

Die Release 0.8 von JVx wird zusammen mit der WebUI und QT Implementierung im Laufe des 3. Quartals 2010 verfügbar sein. Der Showcase unserer WebUI Implementierung wird bereits in den nächsten Wochen online sein.

Ein erster Blick auf unseren Silverlight Showcase

Post to Twitter

Unsere .NET bzw. MONO Anbindungen an JVx befindet sich bereits auf der Zielgeraden. Und frei nach dem Motto "ein Bild sagt mehr als tausend Worte" präsentieren wir Ihnen die ersten Screenshots von unserem Silverlight Showcase.

Die Anwendung befindet sich zwar noch in der Entwicklung, sowohl am Design als auch Funktional wird sich noch das eine oder andere Detail ändern, aber sehen Sie selbst:

Silverlight Login

Silverlight Login

Die Anmeldung

Die Anmeldung an die Applikation erfolgt durch die Eingabe von Benutzername und Passwort. Selbstverständlich können die gleichen Benutzerdaten wie auch in der Java Applikation verwendet werden.

Der Silverlight Client unterscheidet sich zwar optisch vom Java Client, doch die Business Logik wird ohne Souce Code oder Konfigurations- Anpassungen wiederverwendet.

Ein wesentliches Ziel bei der Entwicklung ist, die Vorteile der jeweiligen Technologie ideal zu nutzen!

 
Die Kontaktverwaltung

Das Foto kann bequem per Drag and Drop vom Desktop in die Anwendung gezogen werden. Und weiters ermöglichen wir die Adress Auswahl über das Map Control (siehe nachfolgenden Screenshot).

Ein nicht gleich auf den ersten Blick ersichtlicher Knüller ist das Data Binding. Die Daten werden nämlich nicht via Webservice oder JSON geladen, sondern direkt von der JVx Business Logik. Und für sämtliche CRUD Anweisungen werden die selben Server Objekte verwendet wie auch für den Java Client.

Silverlight Contacts

Silverlight Contacts

 
Silverlight Map

Silverlight Map

Die Adressauswahl

Eine Adresse einzugeben ist nur halb so viel Spaß wie die Adresse auf einer Karte zu suchen. Aus diesem Grunde haben wir das komfortable Map Control integriert.

Da macht das ganze doch gleich viel mehr Spaß!

 

Den Silverlight Showcase werden wir demnächst veröffentlichen. Bleiben Sie also am laufenden!

iPhone Anwendungen mit jQTouch erstellen

Post to Twitter

Eine native iPhone Anwendung setzt nicht nur Objective-C Know How voraus sondern auch eine spezielle Entwicklungsumgebung sowie Mac OS. Doch nicht immer muss es eine native App sein. Wenn auf die Kamera und die Hardware Beschleunigung verzichtet werden kann, stehen sehr gute JavaScript APIs zur Verfügung.

Ein brandneues API steht mit jQTouch bereit.

Fundtruhe - APIs

Post to Twitter

Zum Wochenausklang einige interessante Links für mobile Anwendungen:

  • JSON Serializer

    Ein noch recht junges Projekt für die Objektserialisierung mit JSON.

  • JFXtras

    Im Rahmen des Projektes werden Erweiterungen für Java FX entwickelt. Unter anderem neue Komponenten und Effekte.

  • AiCharts (Kommerziell)

    Eine mächtige Bibliothek für die Erstellung von Charts unter Android.

JVx 0.8 Beta 1

Post to Twitter

Seit heute steht die Beta 1 von JVx 0.8 bereit. Die Versionsnummer deutet auf eher geringe Änderungen zum Vorgänger hin. Doch der Schein trügt. Wir haben extrem hohe Ansprüche in die Release 1.0 und erst wenn alle in unserem Team zustimmen, wird der Schritt gewagt. Auf dem Weg zu 1.0 warten also noch spannende und Feature geladene Versionen.

Was ist nun alles neu und warum lohnt sich der Umstieg?

Neben kleineren und notwendigen Bugfixes lag das Hauptaugenmerk auf

  • Datenbankfeatures
  • Technologie Unabhängige Kommunikation (C#, MONO)
  • Erweiterungen im Bereich des Handling von Business Objekten
  • Minimierung der Requests
  • Code reviews

Wie bereits in einem meiner letzten Beiträge angedeutet, ist es mit JVx nun möglich die Business Logik für .NET/C# bzw. MONO Anwendungen anzubieten. Doch nicht nur die Business Logik an sich sondern im speziellen der Zugriff auf Datenbanken wird auf einfachste Art und weise ermöglicht. Sowohl mit Java als auch mit C# wird wie gewohnt gearbeitet. Die übliche IDE, die gewohnten Frameworks, die bekannten UI Komponenten. Vor allem mit Silverlight ist die Anbindung an JVx ein enormer Gewinn.

Zu den interessanten Datenbankfeatures zählen sicherlich die automatische Übernahme der Default Werte von Spalten und die Berücksichtigung von Check Constraints.
Die Default Werte werden wirksam wenn am Client ein neuer Datensatz erstellt wird. Dann werden die Default Werte vollautomatisch vorbelegt und die Eingabe wird für den Anwender um einiges einfacher und vor allem passieren weniger Fehler.
Die Check Constraints verwandeln einzelne Spalten automatisch in Choice Editoren, sprich der Anwender kann nur die erlaubten Werte eingeben. Im Falle von Ja/Nein Feldern müsste ansonsten immer und immer wieder ein J/N Choice Cell Editor definiert werden. Das erledigt nun JVx. Die einzige Bedingung ist ein sauberes Datenmodell.

Aber unabhängig von der Datenbank, stehen alle diese Features auch als API Funktionen zur Verfügung. Die Default Werte und die erlaubten Eingabewerte sind über Funktionen setzbar und können einfach in der Middleware festgelegt werden. Denn nicht jeder Java Entwickler ist zugleich ein Datenbank Spezialist.

Das wertvollste neue Feature ist aber unangefochten die Performancesteigerung bei der Übertragung der Meta Daten zwischen RemoteDataBook und DBStorage. Die Meta Daten werden nun Standardmässig pro RemoteDataSource gecached (im Normalfall existiert eine RemoteDataSource pro WorkScreen). Sollte ein WorkScreen z.B. 10 RemoteDataBooks enthalten, so wurden bisher 10 einzelne Requests benötigt. Nun reduzieren sich die Requests auf einen einzigen! Doch selbst dieser Request ist im produktiven Betrieb nicht nötig, da die Meta Daten im Normalfall nicht mehr geändert werden.
Aus diesem Grund wurde eine Cache Role eingeführt, die Wahlweise auf Global, DataSource oder Off gesetzt werden kann. Im Entwicklungsstadium verzichtet man auch gerne auf Caching.

Im Bereich der Business Logik wurde die Abhängigkeit zu GenericBean gelockert. Nun ist ein Lifecycle Objekt vom Typ Map ausreichend um die Server Objekte zu verwalten. Natürlich erhält man nur mit GenericBean den vollen Komfort, aber bei der Integration der JVx Lifecycle Objekte in z.B JSF oder Spring, verzichtet man schon mal auf diesen Komfort.

JSF, Spring und JVx? Mit der Beta 1 von JVx 0.8 wird die Integration möglich.

Eine genaue Übersicht der Änderungen finden sie in unserem Support System und der Roadmap zu JVx 0.8.

Fundtruhe

Post to Twitter

Schon länger im Gespräch, nun ist es da. Ein Java API für Amazon's Could: AWS SDK for Java

Weiters gibt es die Berkley DB ab 11g R2, von Oracle, nun auch für Android und die DB bietet zusätzlich ein neues SQL API, basierend nun auf SQLite 3.