Vaadin 7 Cookbook
上QQ阅读APP看书,第一时间看更新

Building any layout with AbsoluteLayout

If the basic layouts offered by Vaadin limit us, and we want to create some other special crazy layout, we can use AbsoluteLayout. There are no limits in this layout. We can insert components into any place we want. In this recipe, we will create a demo of a custom layout, Circle layout. There are also some reasons not to use AbsoluteLayout. They are described in the There's more... section at the end of this recipe.

Building any layout with AbsoluteLayout

How to do it...

Carry out the following steps to create a custom layout using the AbsoluteLayout class:

  1. We create a project with the main UI class called Demo.
    public class Demo extends UI {…}
  2. We will create a class called CircleLayoutDemo that extends AbsoluteLayout.
    public class CircleLayoutDemo extends AbsoluteLayout {...}
  3. Let's use icons from the Runo theme. So we create an array of icon names.
      private String[] icons = {
      "cancel.png", "calendar.png", "document.png",
      "email.png", "globe.png", "help.png",
      "note.png", "ok.png", "trash.png", "user.png" };
  4. In the constructor, we add some mathematical variables to calculate the circle. If we change the radius variable, CircleLayout automatically changes size.
    public CircleLayoutDemo() {  
      double step = 360.0 / icons.length;
      int radius = 70;
      int i = 0;
      int xMargin = 20;
      int yMargin = 20;
      
    }
  5. Now let's create images according the names in the array icons. In the AbsoluteLayout class, components are placed with horizontal and vertical coordinates relative to an edge of the layout area. The distance from the top edge is defined by the xMargin variable and the distance from the left edge is defined by the yMargin variable. So we calculate the x and y coordinates and we use them in the addComponent() method.
      for (String icon : icons) {
        Resource imageResource =
          new ThemeResource("../runo/icons/32/" + icon);
        Image image = new Image(null, imageResource);
        double degrees = Math.toRadians(i * step);
        int x = (int) (Math.cos(degrees) * radius)
        + xMargin + radius;
        int y = (int) (Math.sin(degrees) * radius)
        + yMargin + radius;
        addComponent(image, "left: "+ y + "px; top: "+ x + "px;");
        i++;
      
      }
  6. In the last part of the code in the constructor, we compute and set the width and height of the layout.
      setWidth((xMargin * 4) + (radius * 2), Unit.PIXELS);
      setHeight((yMargin * 4) + (radius * 2), Unit.PIXELS);
    }
  7. In the root Demo class, we can simply add our CircleLayoutDemo class.
    public class Demo extends UI {
      @Override
      public void init(VaadinRequest request) {
        setContent(new CircleLayoutDemo()); 
      }  
    }

How it works...

AbsoluteLayout allows placing components in arbitrary positions in the layout area. The positions are specified in the addComponent() method with horizontal and vertical coordinates relative to an edge of the layout area. The positions can include a third depth dimension, and the z-index, which specifies which components are displayed in front and which are behind other components.

There's more...

In web development in general, AbsoluteLayout is the last resort. In some cases we can use it for special layouts as mentioned with CicrleLayout or we can use it for animation. But there are lots of reasons not to use it. For example, if the font sizes change, the content increases and decreases. If the size of the page is changed, the components aren't wrapped. It's recommended that if we want to do special layouts without the constraints and help from the Vaadin layouting system, we should use CssLayout. CssLayout allows strong control over styling of the components contained inside the layout.

See also