Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Support for RTL Languages / Themes in Vaadin

Roland Baeumler
1 decade ago Apr 07, 2010 9:46am
Marko Grönroos
1 decade ago Apr 07, 2010 3:34pm

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:

  • 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)

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.

Last updated on Apr, 7th 2010
Marko Grönroos
1 decade ago Apr 08, 2010 1:37pm

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.

Roland Baeumler
1 decade ago Apr 09, 2010 11:55am
Marko Grönroos
1 decade ago Apr 09, 2010 1:37pm
Martin Maher
1 decade ago Dec 22, 2010 9:10pm
Henri Sara
1 decade ago Dec 23, 2010 9:02am
omar elhawary
6 years ago Dec 15, 2015 9:37pm

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

   

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]);
                }
            }
        }

    }
/**
* 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;
    }

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;
        }

 

Nick Rapellas
3 years ago Feb 20, 2019 2:25pm
Y J
3 years ago Feb 25, 2019 11:14am