Need a layout advice

Hi
I would like to have a screen layout like I have in the attachment,
So I guess I need that the base layout should be
VerticalLayout
where I can locate [A]
and rest of the comportment [B+C]
.
The # line between [B]
and [C]
means that I have
HorizontalSplitPanel
.
[B]
is a tree that can be expended and [C]
has 3 sub areas:
[C1]

  • Here I will have few buttons and the content here is static
    [C2]
  • A Table where the number of rows and columns may be changed in runtime according to the tree [B]
    navigation.
    [C3]
  • Here I will have few labels (the exact number depends on the tree navigation).

I believe the C components should be on a
VerticalLayout
.


My constraints:

I need that the layout will be all over the screen and I want each of the sub area to consume a fraction of the size.
Example: [A]
should take 15% of the screen height and 100% if the width.
Another example:[B]
should take 85% of the screen height and 25% of the width. If it needs more space - a scrollbar should be used.
If the table needs more space - a scrollbar (around the table) should be used.
Thanks

Avishay
12078.jpg

Well, when you want to fill all the available space no matter the component’s contents, setSizeFull() (i.e. 100% width and height) is a good choice. Similarly, when you want to be sure that your contents won’t get hidden, setSizeUndefined() (i.e. -1% width and height) gives you those scrollbars as long as your component supports them (panel and table both do). If you want your panel both fill the available space and make sure the contents are available, use setSizeFull to the panel itself and setSizeUndefined() to it’s contents (either by getContents().setSizeUndefined() or setContents()). If you want to allocate space in set percentages, or give one (or more) component all the space that would otherwise get left over setExpandRatio(…) is good for that, although the downside is that if you actually don’t have enough space for all the contents the components with positive expandRatios get hidden first. Adding ?debug to your URL and clicking analyze layouts usually gives you good hints if the layout doesn’t seem to behave - there might be some conflicts where one component tries to be exactly the size of its contents while the contents try to only fill whatever space the component has to give. The important thing is to remember that setSizeFull() might mean your component looks smaller than with setSizeUndefined(), and some parts of it might even get hidden no matter what component you are using. There won’t be any scrollbars if the panel’s getContent() has setSizeFull().

I hope that answered to your questions, but if not, feel free to ask more :slight_smile:

Here is what I currently have:

Demo

From the Analyzes output I can see I have some issues…not sure how to handle them.
Visually speaking, I would like to have the following:

  1. The table and the buttons should have less space between them.
  2. The status panel (“The quick brown fox jumps over the lazy dog”) should be pushed to the bottom.
  3. The table should have V & H scrollbars when the screen is getting smaller. (like the tree has).

The code:

package x.y.z.rhevm.integration.view;

import static x.y.z.rhevm.integration.services.misc.Constants.PROPERTY_NAME;

import java.util.Iterator;

import org.springframework.context.ApplicationContext;

import x.y.vaadin.spring.SpringService;
import x.y.z.rhevm.integration.services.IBackEndServices;
import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Reindeer;

@SuppressWarnings("serial")
public class MainDelMeLater extends Application {

	@Override
	public void init() {
		Window mainWindow = null;
		mainWindow = new MainWindow();
		setMainWindow(mainWindow);
	}

	class MainWindow extends Window {
		public MainWindow() {
			  // Our main layout is a horizontal layout
            HorizontalLayout main = new HorizontalLayout();
            main.setSizeFull();
            setContent(main);
            
            final HorizontalSplitPanel horiz = new HorizontalSplitPanel();
            horiz.setSplitPosition(25); // percent
            final ApplicationContext applicationContext = SpringService.getApplicationContext();

            // Tree to the left
            Panel treePanel = getTreePanel(applicationContext);
            horiz.addComponent(treePanel);

            // vertically divide the right area
            VerticalLayout left = new VerticalLayout();
            left.setSizeUndefined();
            
            // buttons on top
            final Panel actionsPanel = getActionsPanel();
            left.addComponent(actionsPanel);
            left.setExpandRatio(actionsPanel, 1.0f);

            final IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
            // table in the middle
            final Panel tblPanel = getTablePanel(backEndServices);
            left.addComponent(tblPanel);

            // Label on bottom
            Panel statusPanel = getStatusPanel(left);
            left.addComponent(statusPanel);
            left.setExpandRatio(statusPanel, 1.0f); 
            addComponent(horiz);
            horiz.addComponent(left);
		}

		private Panel getStatusPanel(VerticalLayout left) {
			Panel textPanel = new Panel(); 
            textPanel.setStyleName(Reindeer.PANEL_LIGHT);
            textPanel.setSizeFull();
            final String brownFox = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. ";
            Label text = new Label(brownFox);
            text.setWidth("500px"); 
            textPanel.addComponent(text);
            return textPanel;
		}

		private Panel getTablePanel(IBackEndServices backEndServices) {
			Panel panel = new Panel();
			panel.setStyleName(Reindeer.PANEL_LIGHT);
			panel.setHeight("80%");
			panel.setWidth(null);
			Table tbl = new Table();
            tbl.setContainerDataSource(backEndServices.getUnifiedRecordContainer());
            tbl.setSortDisabled(true);
            tbl.setPageLength(7);
            panel.addComponent(tbl);
			return panel;
		}
		
		private Panel getActionsPanel() {
			Panel actionPanel = new Panel();
			HorizontalLayout horizontalLayout = new HorizontalLayout();
			Button addbutton = new Button(SpringService.getMessage("action.add"));
			horizontalLayout.addComponent(addbutton);
			Button deleteButton = new Button(SpringService.getMessage("action.delete"));
			horizontalLayout.addComponent(deleteButton);
			horizontalLayout.setSpacing(true);
			actionPanel.addComponent(horizontalLayout);
			actionPanel.setStyleName(Reindeer.PANEL_LIGHT);
			return actionPanel;
		}
		
		private Panel getTreePanel(ApplicationContext applicationContext) {
            Panel treePanel = new Panel(); 
            treePanel.setStyleName(Reindeer.PANEL_LIGHT);
            treePanel.setHeight("100%");
            treePanel.setWidth(null);
            treePanel.getContent().setSizeUndefined();
            addComponent(treePanel);
            Tree tree = new Tree();
            IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
            tree.setContainerDataSource(backEndServices.getADCsContainer());
            tree.setItemCaptionPropertyId(PROPERTY_NAME);
            for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) {
                tree.expandItemsRecursively(it.next());
            }
            treePanel.addComponent(tree);
            return treePanel;
		}
	}
}

Thanks

Avishay

Your layout is quite heavy. The right portion of your split panel contains a panel for each of the three parts. You could e.g. replace it with a single VerticalLayout, where you add HorizontalLayout for the buttons, a Table and a Panel for the labels.

The problems reported in analyze layout are due to your panels don’t have widths nor heights defined.

OK
I have changed the code accordingly.
Here is is:

package x.y.z.rhevm.integration.view;

import static x.y.z.rhevm.integration.services.misc.Constants.PROPERTY_NAME;

import java.util.Iterator;

import org.springframework.context.ApplicationContext;

import x.y.vaadin.spring.SpringService;
import x.y.z.rhevm.integration.services.IBackEndServices;
import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Reindeer;

@SuppressWarnings("serial")
public class MainDelMeLater extends Application {

	@Override
	public void init() {
		Window mainWindow = null;
		mainWindow = new MainWindow();
		setMainWindow(mainWindow);
	}

	class MainWindow extends Window {
		public MainWindow() {
			  // Our main layout is a horizontal layout
            HorizontalLayout main = new HorizontalLayout();
            main.setSizeFull();
            setContent(main);
            
            final HorizontalSplitPanel horiz = new HorizontalSplitPanel();
            horiz.setSplitPosition(25); // percent
            final ApplicationContext applicationContext = SpringService.getApplicationContext();

            // Tree to the left
            Panel treePanel = getTreePanel(applicationContext);
            horiz.addComponent(treePanel);

            // vertically divide the right area
            VerticalLayout left = new VerticalLayout();
            left.setSizeUndefined();
            
            // buttons on top
            final HorizontalLayout actionsLayout = getActionsLayout();
            left.addComponent(actionsLayout);
            left.setExpandRatio(actionsLayout, 1.0f);

            final IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
            // table in the middle
            Table table = getTable(backEndServices);
            left.addComponent(table);

            // Label on bottom
            Panel statusPanel = getStatusPanel(left);
            left.addComponent(statusPanel);
            left.setExpandRatio(statusPanel, 1.0f); 
            addComponent(horiz);
            horiz.addComponent(left);
		}

		private Panel getStatusPanel(VerticalLayout left) {
			Panel textPanel = new Panel(); 
            textPanel.setStyleName(Reindeer.PANEL_LIGHT);
            textPanel.setSizeFull();
            final String brownFox = "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. ";
            Label text = new Label(brownFox);
            text.setWidth("500px"); 
            textPanel.addComponent(text);
            return textPanel;
		}

		private Table getTable(IBackEndServices backEndServices) {
			Table tbl = new Table();
            tbl.setContainerDataSource(backEndServices.getUnifiedRecordContainer());
            tbl.setSortDisabled(true);
            tbl.setPageLength(7);
            return tbl;
		}
		
		private HorizontalLayout getActionsLayout() {
			HorizontalLayout horizontalLayout = new HorizontalLayout();
			Button addbutton = new Button(SpringService.getMessage("action.add"));
			horizontalLayout.addComponent(addbutton);
			Button deleteButton = new Button(SpringService.getMessage("action.delete"));
			horizontalLayout.addComponent(deleteButton);
			horizontalLayout.setSpacing(true);
			return horizontalLayout;
		}
		
		private Panel getTreePanel(ApplicationContext applicationContext) {
            Panel treePanel = new Panel(); 
            treePanel.setStyleName(Reindeer.PANEL_LIGHT);
            treePanel.setHeight("100%");
            treePanel.setWidth(null);
            treePanel.getContent().setSizeUndefined();
            addComponent(treePanel);
            Tree tree = new Tree();
            IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
            tree.setContainerDataSource(backEndServices.getADCsContainer());
            tree.setItemCaptionPropertyId(PROPERTY_NAME);
            for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) {
                tree.expandItemsRecursively(it.next());
            }
            treePanel.addComponent(tree);
            return treePanel;
		}
	}
}

The visual aspect remains the same.
How do I go on?

Thanks

Avishay

I did some progress :grin:
See:
Demo

(Source code attached).
However I still have some open issues:

  1. I want the table to have V & H scrollbar when the screen becomes smaller.
  2. I want the status panel pushed to the bottom.
  3. I want the status panel to be always visible.

Can you please advice?

Thanks

Avishay
12093.java (8.85 KB)

Remove setExpandRatio() from actionsLayout. Set statusPanel height fixed or relative. Set expandRatio 1.0f for the Table. And set fullSize for the left VerticalLayout.

		public MainWindow() {
			  // Our main layout is a horizontal layout
            HorizontalLayout main = new HorizontalLayout();
            main.setSizeFull();
            setContent(main);
            
            final HorizontalSplitPanel horiz = new HorizontalSplitPanel();
            horiz.setSplitPosition(25); // percent
            final ApplicationContext applicationContext = SpringService.getApplicationContext();

            // Tree to the left
            Panel treePanel = getTreePanel(applicationContext);
            horiz.addComponent(treePanel);

            // vertically divide the right area
            VerticalLayout left = new VerticalLayout();
			left.setSizeFull();
            left.setSpacing(true);
            left.setMargin(true);
            left.setSizeUndefined();
            
            // buttons on top
            final HorizontalLayout actionsLayout = getActionsLayout();
            left.addComponent(actionsLayout);
            left.setExpandRatio(actionsLayout, 1.0f);

            final IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
            // table in the middle
            Table table = getTable(backEndServices);
            left.addComponent(table);

            // Label on bottom
            Panel statusPanel = getStatusPanel();
			statusPanel.setWidth("100%");
			statusPanel.setHeight("250px");
            left.addComponent(statusPanel);
            left.setExpandRatio(table, 1.0f); 
            addComponent(horiz);
            horiz.addComponent(left);
		}

Hi
Thanks for the help. :smiley:
I have modified the code and it looks much better now.
However I have some points to improve.
When the screen is showen for the first time the buttons [Add,Delete]
have a vertical gap from the table. Only when the ‘statusPanel’ is shown the gap is getting smaller.

  1. I want to have a smaller gap even when the screen is shown for the first time.
  2. I want the ‘Add’ button to be on the right side of the layout and the ‘Delete’ button to be on the left side. I tried to use “horizontalLayout.setComponentAlignment(…)” but it has no impact.
  3. when the ‘statusPanel’ has lots of info I want to have scrollBar - I tried to call “panel.setScrollable(true);” but it has no impact.

See attached screen captures.
See the code.

Thanks

Avishay
12119.java (12.4 KB)
12120.png
12121.png

  1. Set top alignment for the buttons so they are right after the table
  2. I guess your horizontal layout has undefined size. Set component alignment doesn’t have effect, but if you call setWidth(“100%”), then the horizontal alignment should work.
  3. Your Panel might have undefined size- Set it to relative or fixed size, then the scroll bars should appear when the content would overflow.

Regarding #2:
I have added the “100%” and now the buttons are in the center…:*)
Looking at the DOM I see that the delete button style is:

float: left; margin-left: 0px;

and the Add button style is:

float: left; margin-left: 424px; 

Code:

	private HorizontalLayout getActionsLayout() {
		HorizontalLayout horizontalLayout = new HorizontalLayout();
		horizontalLayout.setWidth("100%");
		handleConnectButton(horizontalLayout);
		handleDeleteButton(horizontalLayout);
		horizontalLayout.setSpacing(true);
		return horizontalLayout;
	}
	
	private void handleConnectButton(final HorizontalLayout horizontalLayout) {
		connectButton = new Button(SpringService.getMessage("action.add"));
		connectButton.setEnabled(false);
		connectButton.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				handleConnectWindow();
			}
		});
		horizontalLayout.addComponent(connectButton);
		horizontalLayout.setComponentAlignment(connectButton, Alignment.BOTTOM_RIGHT);
	}
	
	
	private void handleDeleteButton(final HorizontalLayout horizontalLayout) {
		deleteButton = new Button(SpringService.getMessage("action.delete"));
		horizontalLayout.addComponent(deleteButton);
		horizontalLayout.setComponentAlignment(deleteButton, Alignment.BOTTOM_LEFT);
		deleteButton.setEnabled(false);
		deleteButton.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				// TODO: I18N
				ConfirmDialog.show(
						getWindow(),
						"Please Confirm:",
						"Are you sure you want to disconnect VM " + currentRecord.getVmName() + " from VIP " + currentRecord.getVipIP() + " ?"
								+ "" + "?", "Yes",
						"No", new ConfirmDialog.Listener() {
							public void onClose(ConfirmDialog dialog) {
								// TODO :Call a backend service  and disconnect
								unifiedRecordTable.removeItem(currentRecord);
								deleteButton.setEnabled(false);
							}
						});
			}
		});
	}

See attached picture.

Any idea?

Thanks

Avishay
12127.png

You are adding them in the layout in wrong order.

Oops…
I fixed the order and now it works.:grin:

Thanks

Avishay

About the vertical space between the buttons and the table.
I have modified the code (Added: left.setComponentAlignment(actionsLayout, Alignment.TOP_LEFT):wink:
but got no impact
Here is the code:

public ApplicationsTab() {
        setSizeFull();
        final HorizontalSplitPanel horiz = new HorizontalSplitPanel();
        horiz.setSplitPosition(25); // percent
        final ApplicationContext applicationContext = SpringService.getApplicationContext();

        // Tree to the left
        Panel treePanel = getTreePanel(applicationContext);
        horiz.addComponent(treePanel);
        
        // vertically divide the right area
        VerticalLayout left = new VerticalLayout();
        left.setSizeFull();
        //left.setSpacing(true);
        left.setMargin(true);
        
        final IBackEndServices backEndServices = applicationContext.getBean(IBackEndServices.class);
        // Table
        final Table table = getTable(backEndServices);
        left.addComponent(table);
        left.setExpandRatio(table, (float) 1.0);        
        
        // Action buttons
        final HorizontalLayout actionsLayout = getActionsLayout();
        left.addComponent(actionsLayout);
        left.setComponentAlignment(actionsLayout, Alignment.TOP_LEFT);
        
        // Horizontal separator
        //left.addComponent(new Label("<hr style=\"height:0.5em; width:100%; border:1px solid #000;\" />",Label.CONTENT_XHTML));

        // Status Panel on the bottom
        Panel statusPanel = getStatusPanel();
        left.addComponent(statusPanel);
        left.setComponentAlignment(actionsLayout, Alignment.BOTTOM_LEFT);
        addComponent(horiz);
        horiz.addComponent(left);

	}

and a screen capture as well.

Thanks

Avishay
12128.png

Alignments won’t work because they are both set to the same component and you are giving all the extra space to the table. If you remove the setExpandRatio() and change the second alignment to statusPanel it should work.