Scrolling issue on Vaadin 21 and ApplicationLayout - vaadin

I have a strange problem with the application layout and views which need to be scrolled:
If I create an application with the default App Layout, the drawer toggle is on the top and I add a VerticalLayout with fullsize as view everything is working as expected. But if the vertical content exceeded the height of the browser window (even if I put this content into a scroller), the whole view get scrolled and disappears behind the toggle until the height of the toggle is reached, than scrolling stops.
It seams that setHeight(100, Unit.Percentage) does not considers the height of the toggle.
Has someone a similiar problem?
Edit
Put the following code as a view into an AppLayout and open this on your mobile device e.g. iPhone and you will see the vertical scroller:
#Route(value = "application/test", layout = ApplicationLayout.class)
#PageTitle("Test")
#RolesAllowed({"ROLE_NEWSLETTER_ADMIN", "ROLE_ORGANIZATION_ADMIN"})
public class TestView extends VerticalLayout implements BeforeEnterObserver {
private MenuBar menu;
private Grid<Person> grid;
private Label footerLabel;
public TestView() {
this.setSizeFull();
menu = new MenuBar();
menu.addItem("New");
menu.addItem("Edit");
menu.addItem("Delete");
this.add(menu);
grid = new Grid<>(Person.class);
this.add(grid);
this.expand(grid);
footerLabel = new Label("Number of objetcs: #");
this.add(footerLabel);
}
#Override
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
}
}
AppLayout:
public class ApplicationLayout extends AppLayout implements AfterNavigationObserver {
private ApplicationService applicationService;
private H1 headerTitle;
public ApplicationLayout(ApplicationService applicationService) {
this.applicationService = applicationService;
createHeader();
createDrawer();
this.setPrimarySection(Section.DRAWER);
}
private void createHeader() {
// Define the header
HorizontalLayout header = new Header(new H1("Header"));
addToNavbar(header);
}
private void createDrawer() {
....
}
}

It seams that setHeight(100, Unit.Percentage) does not considers the height of the toggle.
Correct. The 100% is the size of the view port. So if you have e.g. the following
VerticalLayout vLayout = new VerticalLayout();
Button button = new Button();
button.setHeight(50, Unit.Pixels);
HorizontalLayout hLayout = new HorizontalLayout();
hLayout.setHeight(100, Unit.Percentage);
vLayout.add(button,hLayout);
This will produce something where vLayout height is more that viewport height and scroll bar emerges. Instead you should do.
VerticalLayout vLayout = new VerticalLayout();
Button button = new Button();
button.setHeight(50, Unit.Pixels);
HorizontalLayout hLayout = new HorizontalLayout();
hLayout.setHeight(200, Unit.Pixels);
vLayout.add(button,hLayout);
vLayout.expand(hLayout); // or vLayout.setFlexGrow(1.0d, hLayout);

Related

Vaadin flow - Grid column empty

Vaadin 11.0.1
Layout is one top grid and to bottom grid (one on left, one on right)
Here is how I create my page:
public class InformationMainView extends VerticalLayout {
private Grid<AdmisRejet> gridRejet = new Grid<>();
private Grid<Entry<String, String>> admisPropertiesGrid = new Grid<>();
private Grid<AdmisHistory> gridJobHistory= new Grid<>();
public InformationMainView() {
// history (top)
gridJobHistory.setItems(admisHistoryRepository.findAllByOrderByJobExecutionDateDesc());
gridJobHistory.addColumn(AdmisHistory::getJobExecutionDate).setHeader("Date Importation");
gridJobHistory.addColumn(AdmisHistory::getCreatedBy).setHeader("Par");
gridJobHistory.addColumn(AdmisHistory::getUai).setHeader("UAI");
gridJobHistory.addColumn(admisHistory -> admisRejetRepository.findAdmisRejetByAdmisHistory(admisHistory).size()).setHeader("Nb Rejets");
// reject (bottom left)
gridRejet.addColumn(AdmisRejet::getTypeRejet).setHeader("Type rejet");
gridRejet.addColumn(AdmisRejet::getInformation).setHeader("Valeur");
gridRejet.addColumn(getBlockingIconRenderer()).setHeader("Bloquant");
// details (bottom right)
admisPropertiesGrid.addColumn(Entry::getKey).setHeader("Clé");
admisPropertiesGrid.addColumn(Entry::getValue).setHeader("Valeur");
add(gridJobHistory, new HorizontalLayout(gridRejet, admisPropertiesGrid));
The bottom are not render (not even the headers). There is no data in them (normal, because data are populated when I click on the top grid).
But I expected to see at lest column headers...
Here is the render:
I made it work by forcing the width:
HorizontalLayout bot = new HorizontalLayout();
bot.setWidth("100%");
bot.add(gridRejet, admisPropertiesGrid);
add(gridJobHistory, bot);

Width of child vertical layout

I have a HorizontalLayout (let's call it parent). Inside this I have two VerticalLayouts (left's call them left and right).
Left contains just some text, right contains a lot of elements.
Parent has a width of 100% so it takes the full browser width:
parent.setWidth("100%");
Left should take just as much space as it needs, right should take all other space.
How can I do so? I tried all variations described here and there without success. I tried to:
left.setWidthUndefined();
right.setWidth("100%");
left.setWidth("150px");
left.setWidth("30%"); together with right.setWidth("70%");
Nothing had an effect.
Updated source code:
HorizontalLayout parent = new HorizontalLayout();
parent.setCaption("Parent");
VerticalLayout left = new VerticalLayout();
left.setCaption("Left");
VerticalLayout right = new VerticalLayout();
right.setCaption("Right");
parent.addComponent(left);
parent.addComponent(right);
parent.setWidth("100%");
right.setWidth("100%");
parent.setExpandRatio(right, 1.0f);
setCompositionRoot(parent);
I just did a quick test, and the following seems to work:
...
left.setSizeUndefined();
parent.setWidth("100%");
parent.setExpandRatio(right, 1);
...
This is the full code of the test application (without imports):
#Theme("reindeer")
public class ForumUI extends UI {
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = ForumUI.class)
public static class Servlet extends VaadinServlet {
}
public static class SomeComponent extends CustomComponent {
public SomeComponent() {
HorizontalLayout parent = new HorizontalLayout();
parent.setCaption("Parent");
parent.addStyleName("v-ddwrapper-over");
VerticalLayout left = new VerticalLayout();
left.setCaption("Left");
left.addStyleName("v-ddwrapper-over");
VerticalLayout right = new VerticalLayout();
right.setCaption("Right");
right.addStyleName("v-ddwrapper-over");
parent.addComponent(left);
parent.addComponent(right);
left.setSizeUndefined();
parent.setWidth("100%");
parent.setExpandRatio(right, 1);
setCompositionRoot(parent);
}
}
#Override
protected void init(VaadinRequest request) {
setContent(new SomeComponent());
}
}
Here is the documentation for the space "distribution" of the HorizontalLayout component.
The key to solve your problem is to tell the HorizontalLayout component how to expand it's childrens via the layout.setExpandRatio(leftComponent, 1.0f); method.

Can't align JKabel

Well, I have this code:
static class things implements ActionListener {
public void actionPerformed (ActionEvent e) {
JFrame frame4 = new JFrame("More things");
frame4.setVisible(true);
frame4.setResizable(true);
frame4.setSize(1366,730);
JPanel panel = new JPanel();
JLabel label = new JLabel("<html>One thing more</html>");
label.setVerticalAlignment(SwingConstants.BOTTOM);
label.setHorizontalAlignment(SwingConstants.RIGHT);
panel.add(label);
frame4.add(panel);
}
}
But when I run it, the JLabel with the Vertical/horizontal alignment isn't align, why?
That happens because of LayoutManager. Read more about using different LayoutManager's
1)JPanel use FlowLayout as default. Set to right aligning components for that with help of constructor.
2)JFrame use BorderLayout as default. Add your panel to it with parameter BorderLayout.SOUTH.
3) useframe4.setVisible(true); at the end of construction of GUI for avoiding artifacts.
4)use pack()method instead of setting size to JFrame.
JFrame frame4 = new JFrame("More things");
frame4.setResizable(true);
JPanel panel = new JPanel(new FlowLayout(FlowLayout.TRAILING));
JLabel label = new JLabel("<html>One thing more</html>");
panel.add(label);
frame4.add(panel,BorderLayout.SOUTH);
frame4.pack();
frame4.setVisible(true);

Xamarin FlyoutNavigationController does not show section FooterView

I want to implement a flyout navigation in Xamarin.iOS. For this purpose I am using the FlyoutNavigationController, which works good so far.
But now I have to display some additional content underneath the navigation list inside of the flyout-menu (basically an image, some labels and buttons). For this purpose, I wanted to use the FooterView property of the "section" control that holds the menu items.
When I set
section.Footer = "Test";
it will work (I can see the text), but when I use the 'FooterView' property, nothing shows up:
public class ViewController : UIViewController
{
FlyoutNavigationController navigation;
private const string PageNamePage1 = "The first page";
private const string PageNamePage2 = "The second page";
readonly string[] pages =
{
PageNamePage1,
PageNamePage2
};
public override void ViewDidLoad()
{
base.ViewDidLoad();
navigation = new FlyoutNavigationController
{
View =
{
Frame = UIScreen.MainScreen.Bounds
}
};
View.AddSubview(navigation.View);
var elements = pages.Select(page => new StringElement(page) as Element);
navigation.NavigationRoot = new RootElement("Induserv App");
var section = new Section();
section.AddAll(elements);
var uiTextView = new UITextView {Text = "--> This won't show!"};
section.FooterView = new UIView
{
uiTextView
};
navigation.NavigationRoot.Add(section);
navigation.ViewControllers = new UIViewController[]
{
new UINavigationController(new Page1Controller(navigation, PageNamePage1)),
new UINavigationController(new Page2Controller(navigation, PageNamePage2)),
};
}
}
Does anyone have an idea what it needs to display this footer here? Is there another way to put some controls in this panel?
Set a frame for both the footer view and uiTextView, like so:
var uiTextView = new UITextView(new RectangleF(0, 0, 10, 10)) {Text = "--> This won't show!"};
section.FooterView = new UIView(new RectangleF(0, 0, 10, 10))
{
uiTextView
};

VAADIN - set full height of tab content

I have a TabSheet and a tab item.
There is a table inside the tab.
I have set all height to setFullSize but the height of the table does not occupy the whole tab.
Code is here:
public class GvApplication extends Application {
private static Logger log = Logger.getLogger(GvApplication.class.getName());
Window mainWindow;
TabSheet tabsheet;
#Override
public void init() {
setTheme("gv");
mainWindow = new Window("Test");
mainWindow.getContent().setHeight("100%");
tabsheet = new TabSheet();
tabsheet.setSizeFull();
mainWindow.addComponent(tabsheet);
initSMSTab();
setMainWindow(mainWindow);
}
private void initSMSTab() {
VerticalLayout tab = new VerticalLayout();
tab.setMargin(true);
Table table = new Table("Naam");
table.setWidth("100%");
table.setHeight("100%");
table.setSizeFull();
tab.addComponent(table);
tabsheet.addTab(tab);
Tab smsTab = tabsheet.getTab(tab);
smsTab.setCaption("SMS");
}
}
There is a lot of space left under the table. How can I make table use the whole content of the tab?
If a component should occupy all the available space in a layout, you have to invoke setExpandRatio on the layout in addition to invoking setSizeFull on the component. In your case:
tabsheet.setSizeFull();
VerticalLayout rootLayout = new VerticalLayout();
rootLayout.setSizeFull();
rootLayout.addComponent(tabsheet);
rootLayout.setExpandRatio(tabsheet, 1f);
mainWindow.setContent(rootLayout);
By default, when you create new table component, table "page length", it mean rows count, value is 15, this is a reason why table do not set full size of your tab. Only way to set full size is increase table "page length" by table.setPageLength(30).
PS. You can remove this lines, because you already use "table.setSizeFull();"
table.setWidth("100%");
table.setHeight("100%");
EDIT 1
Case with you show on your screens in comment will be only when you resize parent or table component. Try fist of all add ResizeListener to your window and inside listener write something like
// This will return current rendered rows count
int shownRowsCount = table.getVisibleItemIds().size();
table.setPageLength(shownRowsCount);

Resources