Seiten

Montag, 18. November 2013

Vaadin with CDI

Todays post will show a mini tutorial on how to use CDI with the current Vaadin version (7.1.8). To keep it simple, I will just extend the official Vaadin-HelloWorld-Program a bit.

The normal Non-CDI-HelloWorld-Program works like that: There is a "Click Me"-Button on the screen and when you click that button, a label with the text "Thanks for clicking" is added below that button.
I will extend that HelloWorld-Program by using (injecting) our RapidPM-CDILogger which prints a WARN-Message on the console ("Button was clicked").

The project structure looks like the following:



I created that Vaadin-project via Maven (see https://vaadin.com/download).

To get the program working, we have to make the following changes:
  1. Add the Vaadin-CDI-support and the RapidPM-Modules as dependencies in the pom.xml
  2. Create a log4j.properties in the resources-folder to configure the logger
  3. Modify the Vaadin UI-Class (called MyVaadinUI per default)
That's all. So let's start:

1)
Add the following dependency entries to the pom.xml:

<dependency>
      <groupId>com.vaadin</groupId>
      <artifactId>vaadin-cdi</artifactId>
      <version>1.0.0.alpha1</version>
</dependency> 
<dependency>
       <groupId>org.rapidpm.modul</groupId>
       <artifactId>cdi-commons</artifactId>
       <version>1.2-SNAPSHOT</version>
       <scope>compile</scope>
       <type>jar</type>
</dependency> 

The first dependency is needed to get Vaadin working with CDI, the second is needed to use our RapidPM-Logger.
Attention: The logger won't work with cdi-commons in version 1.1.1

2)
Create a file called log4j.properties:

log4j.rootLogger=DEBUG,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

That file is needed for log4j, which is used by our CDILogger. Put it into src/main/resources. I had to create that resources-folder and mark it as a source-folder manually.

3)
Modify the MyVaadinUI-Class so it looks like the following:
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.cdi.CDIUI;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import org.rapidpm.demo.cdi.commons.logger.CDILogger;
import org.rapidpm.module.se.commons.logger.Logger;

import javax.inject.Inject;
import javax.servlet.annotation.WebServlet;

@Theme("mytheme")
@SuppressWarnings("serial")
@CDIUI
public class MyVaadinUI extends UI
{

    /*
    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = MyVaadinUI.class, widgetset = "VaadinWithCDI.AppWidgetSet")
    public static class Servlet extends VaadinServlet {
    }
    */

    @Inject
    @CDILogger
    private Logger logger;

    @Override
    protected void init(VaadinRequest request) {
        final VerticalLayout layout = new VerticalLayout();
        final Button button = new Button("Click Me");
        button.addClickListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                layout.addComponent(new Label("Thank you for clicking"));
                logger.warn("Button was clicked");
            }
        });
        configureLayout(layout, button); //Only configuring layouting-issues
    }

    private void configureLayout(final VerticalLayout layout, final Button button) {
        layout.setMargin(true);
        layout.setWidth("100%");
        layout.addComponent(button);
        setContent(layout);
    }
}
Explanation:
- The @CDIUI Annotation at line 19 is needed to make the project use CDI.
- Recognize that the inner class at lines 24-27 must be commented out (you can delete those lines completely, of course). If this isn't commented out the Logger is not injected properly and a NullPointerException is thrown when calling methods of it.
- The CDILogger is injected in lines 30-32
- When the button is clicked, a label is added to the layout and a WARN-message is posted on the console via our logger (lines 40/41).

-----------------------------

The result looks like the following:

links:
Vaadin-CDI-integration

Samstag, 9. November 2013

SpeedUp from Charts with Streams

Today we I am writing about the possibillity to speedup the JavaFX GUI elements with the new streams-API from JDK8.
Let´s play with the original example from Oracle. The LineChart demo will be used as base for the following. We are collecting/generating values for a line of points for every hundreds step. Al steps between are interpolated with splines. For calculating the splines I am using the jakarta-commons math3 lib. [1]
Normaly the following steps are needed to generate a LineChart. - get the base values to show
- calculate the interpolated values
- create the line-elements
- fill the Line-Chart and show it

Get the base values to show
For this example we are generating the values we are needing. To hold the values for a List of curves I am using a Without streams you could do it like this:
But with streams I could write this in a more compact form. The nice here is the possibility to concat the single steps. But this is only to show the new streams api. There is no parallel part. Calculate the interpolated values Now I will start to caclculate the interpolated values. For this I am using the commons-math3 lib from Apache. The way to do this is short and straid forward. - Get the base values from the curve you want to calculate on
- Choose the algorithm you want to use
- Fill the base values as init into the function
Now we are able to caculate the interpolated values. This is something we can do in parallel for every curve. This means that we can start with the speed up. The importand parts are the ".parallelStream()" to start a Thread for eveery elements of the List and during the "map(v-> ... )" phase the calculation is done. Every task is put to the Root - Fork-And-Join Pool. Create the line-elements The grafical elements for the Line-Chart are created in the same way. In parallel for every curve. Fill the Line-Chart and show it Now the last step is the filling of the Line-Chart itself. This is done in a seriel way. No parralel way is possible in the moment. But this is not the part that could bring a speed-up. Lesson Learned What we can see is the possibillity to speed up the GUI part in several ways. Not only the generating of the values itself. The creation of the grafical elements could be done in parralel too. The seriell Version LineChartSerialDemo, needed for the 11´th round 2.799.209.417ns and the parralel version LineChartDemo was done in 261.545.220ns. This is a speed up of 10 at my MacBookPro. Happy coding..