Using Vaadin Flow Java API I would like to emulate a Vaadin 8 Window feature: particularly I need to emulate Caption behaviour.
I mean a fixed top "Title" not scrollable as the real content of the Dialog. Anyone can tell me some Example I could learn from ?
Thanks in advance
This is the workaround I found.
public MainView() {
Button button = new Button("Click me",
event -> {
Dialog dialog = new Dialog();
HorizontalLayout horizontalLayout = new HorizontalLayout();
VerticalLayout verticalLayout = new VerticalLayout();
Div headerDiv = new Div();
Div bodyDiv = new Div();
bodyDiv.getElement().getStyle().set("overflow", "auto");
bodyDiv.getElement().getStyle().set("max-height", "420px"); // !!!
dialog.add(headerDiv, bodyDiv);
headerDiv.add(horizontalLayout);
bodyDiv.add(verticalLayout);
horizontalLayout.add(new Label("Hi there !"));
for (int i = 1; i <= 20; i++) {
verticalLayout.add(new TextField("TextField_" + i));
}
dialog.open();
});
add(button);
}
The trouble is that I have to fix max-height size to avoid scrolling of all the contained components. So I cannot take advantage from the auto-size behaviour of the Dialog Container. Also tried using setFlexGrow, but I did not reach the solution.
Any Hint ?
In Vaadin 10+ there is no component called Window, but there is component called Dialog. It does not have Title like Window, but otherwise it has similar baseline. I.e. it is popup. Based on your question you have found already that.
Dialog itself is component container, which means you can add components there. I would just create e.g two Divs (the simplest of the layout components in Vaadin 10). I would style the first one to have fixed height and place the Title there. And then I would apply component.getElement().getStyle().set("overflow", "auto") to the other one, which is the actual content body. The mentioned style will enable the scrollable feature. You could potentially use VerticalLayout / HorizontalLayout instead of Div as well depending what you need.
See also: https://vaadin.com/docs/v10/flow/migration/5-components.html
Related
I would like to have a customized Dialog styling, having another background color and a rounded border, as it looks nicer than the gray rectangle that comes by default.
This is partially possible, by styling the Contentpane of the Dialog. The problem is, that the underlying Dialog Style is still there, in which the contentpane is shown. And it seems the Dialog UDID itself cannot be changed, nor can the "Dialog" style be overwritten in the designer nor by code.
Form hi = new Form();
hi.getUnselectedStyle().setBgColor(0xffffff);
Button but = new Button("open dialog");
but.addActionListener(e -> {
Dialog d = new Dialog(BoxLayout.y());
d.setUIID("Container"); // this line has no effect, the outside dialog component is still visible
Style s = d.getContentPane().getUnselectedStyle();
s.setBorder(RoundRectBorder.create());
s.setBgColor(0x00ff00);
s.setBgTransparency(255);
s.setMargin(5, 5, 5, 5); // adding some margin between contentpane and Dailog container, to be more obvious
d.setDisposeWhenPointerOutOfBounds(true);
// title
Label title = new Label();
title.setText("Confirmation");
d.add(title);
// body field with spanlabel info text
SpanLabel bodyLabel = new SpanLabel("Body Text");
d.add(bodyLabel);
// delete button
Button okButton = new Button("Ok");
okButton.addActionListener(e2 -> {
d.dispose();
});
// exit button
Button exitButton = new Button("Cancel");
exitButton.addActionListener(e3 -> {
d.dispose();
});
d.add(GridLayout.encloseIn(2, okButton, exitButton));
d.show();
});
hi.add(but);
hi.show();
In above image, the outermost dark gray is the tinted area outside the dialog. The green is the content pane with the intended rounded border. the light grey in between comes from the Dialog style that I would like to get rid off.
Can this be done?
Short answer: setDialogUIID("Container");
However dialogs are a bit problematic to customize via code, I would strongly recommend styling them via the designer/css as we just didn't design them for hand styling and so you're relying on internal implementation details that might break.
When you invoke getContentPane() on the Dialog you're styling the content pane of the Dialog. Not the Dialog itself so the dialog styling still has the non-transparent background. You can use getDialogStyle() to style the Dialog itself. I'm not sure how well that will work.
The AbsoluteLayout in Vaadin 8 (Framework) enables pixel-position-oriented placement of widgets within a layout. While not my first layout of choice, the AbsoluteLayout is suited to porting code from other UI-building platforms that use pixel-position-oriented layout.
Example code from the manual:
// A 400x250 pixels size layout
AbsoluteLayout layout = new AbsoluteLayout();
layout.setWidth("400px");
layout.setHeight("250px");
// A component with coordinates for its top-left corner
TextField text = new TextField("Somewhere someplace");
layout.addComponent(text, "left: 50px; top: 50px;");
I can see that the passed argument is simply CSS coding. But I am no HTML/CSS wizard, that’s why I am using Java-based Vaadin in the first place.
The migration guide for moving from Vaadin 8 (Framework) to Vaadin 10 (Flow) says in this list of components that the AbsoluteLayout from 8 is not included in 10, nor do they plan to add it in the future. But that page does offer this note about replacement for AbsoluteLayout:
Very easy to achieve the same in V10 using e.g. Div
Can someone explain what this would mean in a Java-based Vaadin app? Perhaps an example?
How might a person conveniently and routinely do pixel-positioning of widgets in a Vaadin 10 Flow app?
As your request for an "Hello World" example app, I downloaded the Project Starter with Spring Starter from https://vaadin.com/start and combined Tatu's solution with your example usage code. You can find it at https://github.com/Peppe/absolute-layout-demo.
You can test it live with the following commands in terminal / command line:
https://github.com/Peppe/absolute-layout-demo.git
cd absolute-layout-demo
mvn spring-boot:run
I created a class called AbsoluteLayout, with it's entirety looking like this:
public class AbsoluteLayout extends Div {
public AbsoluteLayout() {
getElement().getStyle().set("position", "relative");
}
public void add(Component component, int top, int left) {
add(component);
component.getElement().getStyle().set("position", "absolute");
component.getElement().getStyle().set("top", top + "px");
component.getElement().getStyle().set("left", left + "px");
}
}
Only change that I did, compared to what Tatu said, was to give the position relative to the parent layout. This makes the position of the children added to the layout relative to the layout, and not the body (or parent position relative in the DOM structure). Otherwise the component would be in top:50px, left:50px from browser corner.
Then the usage class looks like this:
#HtmlImport("styles/shared-styles.html")
#Route
public class MainView extends VerticalLayout {
public MainView() {
setClassName("main-layout");
//Just to add some content on the page to test relative position
for (int i = 0; i<5; i++){
add(new Div(new Text("Hello")));
}
// A 400x250 pixels size layout
AbsoluteLayout layout = new AbsoluteLayout();
layout.setWidth("400px");
layout.setHeight("250px");
// A component with coordinates for its top-left corner
TextField text = new TextField("Somewhere someplace");
layout.add(text, 50, 50);
add(layout);
}
}
I added a few lines of text before the layout to add some rows of text, just to test out the position:relative mentioned above.
Hope this helps and gets you on the right path. As you notice, this "AbsoluteLayout" doesn't have really any code to it - it is just a div. You can do this same trick with any layout in your app if you want to place one element into a relative position.
The simplest way in Java-based Vaadin app is to use Div as the layout and add components there.
For each component you want to position you need to apply CSS styles, there is Java API for that, i.e. component.getElement().getStyle().
It could be something like
public void setPosition(Component component, int x, int y) {
component.getElement().getStyle().set("position","absolute");
component.getElement().getStyle().set("top",y+"px");
component.getElement().getStyle().set("left",x+"px");
}
Probably you want to extend Div and the above method (that makes rudimentary AbsoluteLayout)
See also
https://developer.mozilla.org/en-US/docs/Web/CSS/position
I am creating a app for both android and ios using xamarin and mvvmcross.
In the ios app I want to add outer vertical stackview having nested horizontal stackviews. Basically I just want to create a basic person details screen where will be Label on left and textfield on right which will go in one horizontal stackview and like this there will many horizontal stackviews nested in outer vertical stackview.
I am looking for such example on internet but seems most of the examples are in swift but I was hardly able to find some in c#.
Can someone please help.
Thanks,
Santosh
UIStackView leverages the power of Auto Layout and Size Classes to manage a stack of subviews, either horizontally or vertically, which dynamically responds to the orientation and screen size of the iOS device. You can learn about it through this documentation.
In your case, we can construct a vertical stack to place several horizontal stack:
UIStackView verticalStack = new UIStackView();
View.AddSubview(verticalStack);
verticalStack.Axis = UILayoutConstraintAxis.Vertical;
verticalStack.TranslatesAutoresizingMaskIntoConstraints = false;
// Use auto layout to embed this super vertical stack in the View. Also there's no need to set the height constraint, vertical stack will automatically adjust that depending on its content
verticalStack.LeadingAnchor.ConstraintEqualTo(View.LeadingAnchor).Active = true;
verticalStack.TopAnchor.ConstraintEqualTo(TopLayoutGuide.GetBottomAnchor()).Active = true;
verticalStack.TrailingAnchor.ConstraintEqualTo(View.TrailingAnchor).Active = true;
for (int i=0; i<10; i++)
{
// Here try to put some horizontal stack with Label on left and textfield on right in the father stack.
UIStackView horizontalStack = new UIStackView();
horizontalStack.Distribution = UIStackViewDistribution.EqualSpacing;
horizontalStack.Axis = UILayoutConstraintAxis.Horizontal;
// UIStackView should use AddArrangedSubview() to add subviews.
verticalStack.AddArrangedSubview(horizontalStack);
UILabel textLabel = new UILabel();
textLabel.Text = "text";
UITextField textField = new UITextField();
textField.Placeholder = "enter text";
horizontalStack.AddArrangedSubview(textLabel);
horizontalStack.AddArrangedSubview(textField);
}
But if every horizontal stack's subViews are almost the same style and layouts. Why not try to use UITableView? You just need to set the single cell's contents and layouts, then use it in the tableView. Moreover this control is reused and scrollable.
I want to implement a list in Android that contains some customized views.
My problem is that I want the the views will be put one after the other with a little overlap between them. like in the following schema:
I also want to control this overlap in such a way that when the user clicks on one of the items, they will move apart from each other.
I tried to extend ListView but it seems to be very obscured, any suggestions?
Edit:
This can be more clear:
I did it by setting the divider height to -50dp.
this is exactly what I want to achieve, but somehow it doesn't reflect on my app.
I managed to achieve this by using scroll view with a single relative layout as a child.
I then dynamically place the views by defining a rule and margin:
for (int i = 0; i < 30; i++) {
TextView tv = new TextView(context);
tv.setText("Text \n Text" + i);
tv.setBackgroundColor(i % 2 == 0 ? Color.RED : Color.GREEN);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
lp.leftMargin = 0;
lp.topMargin = (i * 45);
rl.addView(tv, lp);
}
Later, you can control the positioning of the sub-views by changing their y value (for example: if you want to add animation).
This is the final result:
This can probably be achieved by using the Camera.setTranslate function. See Android: Vertical ListView with overlaped rows and Android: vertical 3d listview for similar questions (with solutions)
First of all, I'm a long time Java/Swing developer. I recently installed JavaFX 2.2 to play around with.
I'm creating a fairly simple app, whose main window has a toolbar on top and content in the rest of the window. The obvious way to accomplish this is to use a BorderPane, and stick a ToolBar into the top section. So far, so good. However, I would like some of the controls in the toolbar to be at the left edge of the window, and some at the right edge. I can find no way to do this. I can put an invisible spacer object into the toolbar, but I only know how to give it a fixed width; it doesn't resize when the window is resized.
So I thought that instead of using a ToolBar object, I'll just use an HBox; it should be equivalent to a horizontally-oriented Swing Box object, right? And the Swing Box class has a createHorizontalGlue() method that inserts an auto-sizing spacer. Well, I can't find an equivalent in the JavaFX HBox class. Is there no simple way to do this?
I figured out how to do it using an HBox instead of a ToolBar to hold the controls; the key is the HBox.setHgrow() method, which allows you to set a spacer object to grow to fill the available space. I still don't know if it's possible to do this with an actual ToolBar instance.
/**
* Creates and populates the Node that serves as the window toolbar.
*
* #return a newly constructed and populated toolbar component
*/
private Node makeToolbar() {
// Auto-sizing spacer
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
// Horizontal box containing toolbar controls
HBox box = new HBox();
box.setPadding(new Insets(8));
box.setAlignment(Pos.CENTER);
box.getChildren().addAll(openButton, spacer, resizeSlider);
// Colored background panel with drop shadow
Pane bgRect = new Pane();
bgRect.setStyle("-fx-background-color: #e0e0e0;");
bgRect.setEffect(DropShadowBuilder.create().width(1).build());
// StackPane to hold box and rectangle
StackPane stack = new StackPane();
stack.getChildren().addAll(bgRect, box);
return stack;
}
i do it this way:
private Node makeFooter(Node left, Node right) {
ToolBar footer = new ToolBar();
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
spacer.setMinWidth(Region.USE_PREF_SIZE);
footer.getItems().addAll(left, spacer, right);
return footer;
}
hope i could help someone