Support for RTL Languages / Themes in Vaadin

We are currently evaluating Vaadin to use as the framework for our application.

One requirement of our application is that the it supports RTL (right-to-left) user interface for our Arabic installations. Depending on the user that logs on the UI has to be displayed in RTL layout or in LTR layout.

I know that GWT basically supports RTL themes but that there is currently no built-in support in Vaadin for it (there is already a
Vaadin ticket
for it however.).

Searching the forums I’ve found this
post
,
where it states that the RTL support has to be implemented in the application logic.

Can anyone guide me in some direction how this can be accomplished? Does it mean that we would have to programm separate layouts (one for RTL and one for LTR)? Or is there a more generic approach to it?

As noted in the ticket and in the older forum post, there is no particular support for right-to-left languages yet. The most relevant issues are, I suppose:

[list]

[]
Layout order in HorizontalLayout and GridLayout (easy to solve)
[
]
Caption alignment (can probably be solved with a theme)
[]
Captions in FormLayout (hard to solve)
[
]
Alignments (should be automatically reversed)
[]
Tooltips and popups (hard to solve)
[
]
Select, ComboBox, Tree, Menu, etc. (hard or very hard to solve)

[/list]What else? I don’t think there are any huge mixed-language issues, as those are mostly a matter of text rendering. HTML provides rather good support for Arabic and other RTL languages, so rendering should not be an issue.

You can solve some of the issues by writing a simple helper to build layouts and make style settings, etc.

For example:


/ A helper class for managing both LTR and RTL layouts
class RTLManager {
    boolean rightToLeft;
    
    public RTLManager(Locale locale) {
        // The Java locale data doesn't know the direction,
        // so we must deduce it here
        if (locale.getLanguage().equals("ar"))
            this.rightToLeft = true; 
        else
            this.rightToLeft = false;
        
    }
    
    public void addComponent(HorizontalLayout layout, Component c) {
        if (rightToLeft) {
            layout.addComponentAsFirst(c);
            layout.setComponentAlignment(c, Alignment.TOP_RIGHT);
            
            // To allow further customization in a theme
            c.addStyleName("right-to-left");
        } else
            layout.addComponent(c);
    }
}

// Same in both English and Arabic
for (String language: new String[] {"en", "ar"}) {
    // Set the application locale
    Locale locale = new Locale(language);
    
    RTLManager rtlManager = new RTLManager(locale);
    
    // Get some strings for the language
    ResourceBundle bundle = ResourceBundle.getBundle(
            RightToLeftStrings.class.getName(),
            locale);
    
    // Adding components to this layout needs to be managed
    // with the RTL manager
    HorizontalLayout horlayout = new HorizontalLayout();
    horlayout.setSpacing(true);
    
    InlineDateField df = new InlineDateField();
    df.setLocale(locale);
    df.setResolution(DateField.RESOLUTION_DAY);
    rtlManager.addComponent(horlayout, df);

    Label ipsum = new Label(bundle.getString("Ipsum"));
    rtlManager.addComponent(horlayout, ipsum);
    
    Button ok = new Button(bundle.getString("OkKey"));
    rtlManager.addComponent(horlayout, ok);
    
    layout.addComponent(horlayout);
}

See
the example on-line
.

Ok, I checked that captions and TextField content can be right-aligned easily.

/* Captions */
.v-caption-right-to-left .v-captiontext {
    float: right;
}

/* TextField content */
.v-textfield-right-to-left {
    text-align: right;
}

/* This actually works for DateField */
.v-datefield-right-to-left {
    direction: rtl;
} 

I updated the
on-line example
.

For Forms, you can use the attachField() method in Vaadin 6.3 to customize the layout.

Well, these are really just hacks just to get at least the most essential components work. Many problematic components, such as the Tree, would probably require extensive client-side changes. So, for now, RTL languages are really restrictive for Vaadin and, in effect, not feasible.

Thanks a lot for your explanation and code samples. With this approach and with avoiding usage of some problematic components like the Tree, I think it would be possible to create a user interface that satisfies a RTL language speaking person.

I was hoping though that implementing “native” RTL support wouldn’t be a too big issue because the GWT support looks good, even for components like Tree.

With “client-side changes” do you mean changes in the “V”-classes like e.g. VTree?
If I’ve understood the architecture correctly these classed are reading the UIDL stream and then create the GWT Widget based on that. But VTree doesn’t extend the GWT Tree class, it extends FlowPanel, so the GWT Tree isn’t used?

Yes, the “V”-classes. While many of them use the GWT implementations, many others do not, for various technical reasons, typically because of some limitations in GWT. RTL support is therefore not so small task, as it has to be done separately for a large part of the UI features.

Hi,

I’m just wondering if there has been any movement on the RTL front since the original discussion. I ask as we are starting a new project in January 2011 and are evaluating Vaadin for our requirements. First impressions are very good, however the lack of RTL support is a show stopper for us. Are there any plans for encorporating support into a future version and if so in what sort of time frame?

Regards
Martin

Disclaimer: this is my personal view only.

I believe that implementing full RTL support in Vaadin and making sure it works (and will continue to work) would be a major undertaking for the core development team, especially as we do not have previous experience in developing RTL applications. As there are many high-priority items in the queue for Vaadin, I do not believe we would (nor should) spend significant effort on this in the near future.

It might be possible to write RTL applications with Vaadin, but this would probably require more than a little work from the application developers, and there is no guarantee that everything in Vaadin core works with RTL - some features almost certainly will not work cleanly. Themes would definitely need work for a smooth RTL experience, and some components would probably not fit very well in a RTL application.

In short, if full and smooth RTL experience is an absolute requirement, I would recommend looking at other solutions. If you are willing to test out things and spend effort on this (probably also patching Vaadin) and the main RTL requirements are being able to type text RTL etc., Vaadin might work.

If you do look at this in more detail, good feedback on the biggest RTL showstoppers (and possibly patches to address the issues) in Vaadin would be welcome.

you can also use this code for gridlayout
after you fill the gridlayout you call the below method applyRTL() to rearrange the components and the column expand ratios and mirroring the alginmenets

[code]

public void applyRTL() throws Exception {
RtlManager rtlManager = new RtlManager();
int columns = getColumns();
int rows = getRows();

    LayoutBehavior layoutBehavior = new LayoutBehavior[rows]

[columns]
;

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < columns; c++) {
            layoutBehavior[r]

[c]
= new LayoutBehavior();
layoutBehavior[r]
[c]
.setComponent(getComponent(c, r));
layoutBehavior[r]
[c]
.setXposition(columns - 1 - c);
layoutBehavior[r]
[c]
.setYposition(r);
layoutBehavior[r]
[c]

                    .setColumnExpandRatio(getColumnExpandRatio(c));
            layoutBehavior[r]

[c]
.setRowExpandRatio(getRowExpandRatio(r));
if (layoutBehavior[r]
[c]
.getComponent() != null) {

                Alignment componentAlignment = rtlManager
                        .mirroringComponent(getComponentAlignment(getComponent(
                                c, r)));

                layoutBehavior[r]

[c]
.setAlignment(componentAlignment);
}
}
}

    removeAllComponents();
    setSize(1, 1);

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < columns; c++) {
            if (layoutBehavior[r]

[c]
.getComponent() != null) {

                addComponent(layoutBehavior[r]

[c]
);
}
}
}

}

[/code]

[code]
/**

  • NTG Clarity co.
    • @author OMAR ELHAWARY
    • @since 15/12/2015
    • @param componentAlignment
    • @return
    • @explanation
    • this mirror for RTL to mirror the allignement
      */
      public Alignment mirroringComponent(Alignment componentAlignment) {
      Alignment mirorredAlignment = componentAlignment;
      if (componentAlignment.equals(Alignment.BOTTOM_LEFT)
      || componentAlignment == Alignment.BOTTOM_LEFT) {// 9
      mirorredAlignment = Alignment.BOTTOM_RIGHT;
      } else if (componentAlignment.equals(Alignment.BOTTOM_RIGHT)
      || componentAlignment == Alignment.BOTTOM_RIGHT) {// 10
      mirorredAlignment = Alignment.BOTTOM_LEFT;
      } else if (componentAlignment.equals(Alignment.TOP_LEFT)
      || componentAlignment == Alignment.TOP_LEFT) {// 5
      mirorredAlignment = Alignment.TOP_RIGHT;
      } else if (componentAlignment.equals(Alignment.TOP_RIGHT)
      || componentAlignment == Alignment.TOP_RIGHT) {// 6
      mirorredAlignment = Alignment.TOP_LEFT;
      } else if (componentAlignment.equals(Alignment.MIDDLE_LEFT)
      || componentAlignment == Alignment.MIDDLE_LEFT) {// 33
      mirorredAlignment = Alignment.MIDDLE_RIGHT;
      } else if (componentAlignment.equals(Alignment.MIDDLE_RIGHT)
      || componentAlignment == Alignment.MIDDLE_RIGHT) {// 34
      mirorredAlignment = Alignment.MIDDLE_LEFT;
      }
      return mirorredAlignment;
      }
      [/code]also for horizontal layout you have to mirror the alignement using that last method

for formlayout, accordion, tree you have to create new class extends vaadin formlayout and edit its constructor to add rtl style from the scss as below

/**
 *NTG clarity co.
 * @author OMAR ELHAWARY
 * @since 4/10/2015
 */
public class MyFormLayout extends FormLayout {

    public MyFormLayout() {
        super();
        addStyleName("rtl");
       
    }

    public MyFormLayout(Component... children) {
        super(children);

    }

}

scss code

.rtl{
        direction:rtl;
        }

Really old thread, really new request! :slight_smile:
So where is the
LayoutBehavior layoutBehavior = new LayoutBehavior[rows]
[columns]
; ???
(I’m using Vaadin 7 btw)

Thanks!

How efficeiently can we make RTL support including tables and grid ?