I would like to use a custom icon from a picture file in Vaadin 10.
Up to Vaadin 8 it was possibleto load the icon file via ExternalResource:
public final static Resource MY_ICON = new ExternalResource("VAADIN/images/my_icon.png");
and then just use the resource as icon:
Button button = new Button("My Button text");
button.setIcon(MY_ICON);
The setIcon method in Vaadin 10 requires a Component as parameter. How can i load my Icon into a Component? Is there some out of the box solution in vaadin 10?
I would prefer a solution with pure java like in vaadin 7/8.
I'd recommend putting your icon file as /src/main/webapp/my_icon.png (or /src/main/resources/META-INF/resources/my_icon.png if packaging as a .jar). You can then use it anywhere in your application using the built-in com.vaadin.flow.component.html.Image component, e.g. add(new Image("my_icon.png", "My icon"));.
I will post also my own solution since its specific for Button Icon Styling.
You have to load the icon file into a vaadin Image (com.vaadin.flow.component.html.Image) first. but it also requires some additional styling to position the icon correctly in the button.
import com.vaadin.flow.component.html.Image;
public enum MyIcons {
ICON_1("frontend/img/icon_1.png", ""),
ICON_2("frontend/img/icon_2.png", ""):
private String url;
private String alt;
MyIcons(String url, String alt) {
this.url = url;
this.alt = alt;
}
public Image create() {
Image image = new Image(url, alt);
image.getStyle().set("vertical-align", "middle"); // otherwise the icon will be just on the top left corner in the button
return image;
}
/**
* marign right distance if using Icon in Button with Text. so there is space between the icon and the button text
* #param margin_right
* #return
*/
public Image create(int margin_right) {
Image image = create();
image.getStyle().set("margin-right", margin_right+"px"); //some space between icon and button text
return image;
}
}
usage:
Button button = new Button();
button.setIcon(MyIcons.ICON_1.create());
Button buttonWithText = new Button("My button text");
buttonWithText.setIcon(MyIcons.ICON_1.create(), 10); //10px space between icon and button text
Related
I created a custom dialog with my own panes and controls in it. But the dialog has a white border default which I want to remove. Here is an example with a single image:
I tried using ScenicView but couldn't find a way to catch the dialog layer and modify it:
public class MainView extends View {
Image img = new Image("https://i.stack.imgur.com/7bI1Y.jpg", 300, 500, true, true);
public MainView(String name) {
super(name);
Button b = new Button("Pop");
b.setOnAction(e -> {
Dialog<Void> dialog = new Dialog<>();
dialog.setOnShown(e2 -> {
Parent parent = getParent();
Pane p = (Pane) parent.lookup(".dialog");
p.setPadding(new Insets(0));
});
dialog.setGraphic(new ImageView(img));
dialog.showAndWait();
});
setCenter(b);
}
}
Best i got was removing the flowpane child to remove some of the lower part
dialog.setOnShown(e2 -> {
Parent parent = getParent();
Pane p = (Pane) parent.lookup(".dialog");
p.getChildren().removeIf(c -> (c instanceof FlowPane));
System.out.println(p.getChildren());
});
Removing the VBox moves the dialog which i don't want to do and changing its padding also dose nothing.
As you can see with ScenicView, the Dialog has the dialog style class.
One easy way to modify the dialog style is via css. Just add a css file to your view, and set:
.dialog {
-fx-background-color: transparent;
}
That will set the background transparent, instead of the default white color.
If you want to remove the borders instead, then you can play with padding. As you can also see with ScenicView, the dialog has a VBox with style class container for the content in the center, and the flow pane for the buttons at the bottom, with style class dialog-button-bar.
Before anything, just use the setContent method to add the image instead of the setGraphic one:
dialog.setContent(new ImageView(img));
And this will be required to remove all the borders, and let the image take the whole dialog:
.dialog,
.dialog > .container,
.dialog > .dialog-button-bar {
-fx-padding: 0;
}
I have added a popup window to my main UI as follows:
Window component = new Window();
UI.getCurrent().addWindow(component);
Now, I want my popup to be centered horizontally and e.g. 40 pixels from the top of the screen. As far as I can see Vaadin has 4 methods for positioning my window.
component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)
None of these are really what I want. I was hoping at first that setPositionY might help me. This does allow me to get the right distance from the top, but the x-position is now set to 0, where I wanted it to be centered.
The setPosition might have helped if I was able to calculate what the x-position should be, but this would require me to know the width of the component in pixels, but component.getWidth just tells me 100%.
Next I tried to use CSS styling on the component, writing and explicit css rule and adding it to the component with addStyleName. It seems though that Vaadin overrides whatever I wrote in my css with its own defaults...
Any ideas how to get my Window component positioned correctly?
I used the methods getBrowserWindowWidth() and getBrowserWindowHeight() from the com.vaadin.server.Page class for this.
I centered my "log" window horizontally in the lower part of the browser window with
myWindow.setHeight("30%");
myWindow.setWidth("96%");
myWindow.setPosition(
(int) (Page.getCurrent().getBrowserWindowWidth() * 0.02),
(int) (Page.getCurrent().getBrowserWindowHeight() * 0.65)
);
Solution 1: Use SizeReporter
Indeed, setPositionY() will reset the window's centered property to false. As the width of your pop-up and that of your browser window are not know before they appear on the screen, the only way I know to get those values is to use the SizeReporter add-on. Its use is quite straightforward:
public class MyUI extends UI {
private Window popUp;
private SizeReporter popUpSizeReporter;
private SizeReporter windowSizeReporter;
#Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
addWindow(popUp);
popUpSizeReporter = new SizeReporter(popUp);
popUpSizeReporter.addResizeListenerOnce(this::centerPopUp);
windowSizeReporter = new SizeReporter(this);
windowSizeReporter.addResizeListenerOnce(this::centerPopUp);
}
private void centerPopUp(ComponentResizeEvent event) {
int popUpWidth = popUpSizeReporter.getWidth();
int windowWidth = windowSizeReporter.getWidth();
if (popUpWidth == -1 || windowWidth == -1) {
return;
}
popUp.setPositionX((windowWidth - popUpWidth) / 2);
}
}
This piece of code will be okay as long as you don't resize the pop-up. If you do, it will not be automatically recentered. If you replace addResizeListenerOnce() by addResizeListener() then it will automatically recenter the pop-up but you'll get some "UI glitches" as the add-on sends resize events almost continually while you're resizing your pop-up...
You could try to do it using CSS, but I personally avoid CSS as much as I can with Vaadin :).
You'll need to recompile the widgetset after you've added the add-on as a dependency.
Solution 2: Use com.vaadin.ui.JavaScript
I won't vouch for the portability of this solution but I guess it will work on most modern browsers.
public class MyUI extends UI {
private Window popUp;
#Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
popUp.addStyleName("window-center");
addWindow(popUp);
// Add a JS function that can be called from the client.
JavaScript.getCurrent().addFunction("centerWindow", args -> {
popUp.setPositionX((int) ((args.getNumber(1) - args.getNumber(0)) / 2));
});
// Execute the function now. In real code you might want to execute the function just after the window is displayed, probably in your enter() method.
JavaScript.getCurrent().execute("centerWindow(document.getElementsByClassName('window-center')[0].offsetWidth, window.innerWidth)");
}
}
I have two Grids (both in its own panel), and want to navigate between them using the Tab Key.
To do that I'm trying to focus the Grid inside a Panel (If Tab is pressed, the Grid should gain focus, so I can use the up/Down key to select Items).
Vaadin doesn't provide a .focus() method for Grid. Is there any solution so I can focus the Grid anyway?
Here is small example which shows working scenario with
Tab key pressed
Arrows down/up should points to a row (exactly in Valo this is presented as contour around one cell)
Space makes row selected (if Grid has enabled selection!) - row should be highlighted.
Code example:
#Theme ( ValoTheme.THEME_NAME )
public class MyUI extends UI {
public class A {
String a;
String b;
A(String a, String b) {
this.a = a;
this.b = b;
}
// getters & setters
}
#Override
protected void init ( VaadinRequest vaadinRequest )
{
Grid g = new Grid();
List<A> list = Arrays.asList(new A("a", "b"), new A("aa", "bb"),
new A("aaa", "bbb"));
BeanItemContainer<A> items = new BeanItemContainer<>(A.class, list);
g.setContainerDataSource(items);
Panel p = new Panel(g);
setContent(p);
}
}
Tested: Vaadin 7.5, Java 8, Tomcat 8.
You could try to use:
setFocusedComponent(p);
after setContent(p). This should exactly tells Vaadin to make panel focused. But you still must press tab - once or more (depending on rest of components, which you placed on screen).
But make sure:
Grid is selectable.
Maybe you should press Tab more than once.
Depending on Theme there could be different effects of getting focus (or even select state). It is also possible that you use some predefined project which has blocked grid css to make it lighter. So check if you can highlight one row by click on it.
Without more information I can't help more.
The OP write in an edit:
Solved the problem using Javascript/Jquery. Added this to my Panel that contains the Grid:
public class FileTable extends Panel
{
String id;
public FileTable(String id)
{
this.id=id;
Grid table = new Grid();
initGrid();
fileTable.setId(id);
}
public void focus()
{
JavaScript.getCurrent().execute("$(\"#"+id+" table:first td:first\").click();");
}
}
I am trying to build a screen in BlackBerry. In which there should be a second title bar just below the original title bar. Also the second title bar should be fixed and it should not be scrolled with vertical scroll.
Need some advice on this issue.
You can add the second title and the original title bar on a VerticalFieldManager. Then just set that VerticalFieldManager as title, as it's possible to set any Field, Manager instance as title.
Check public void setTitle(Field title) and following example.
public class DemoScreen extends MainScreen {
public DemoScreen() {
super();
// Prepare a Custom Title
long style = NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR | USE_ALL_WIDTH;
VerticalFieldManager myTitle = new VerticalFieldManager(style);
// Set background color.
myTitle.setBackground(BackgroundFactory.createSolidBackground(Color.GRAY));
// Add any numbers/types of field
myTitle.add(new LabelField("First line."));
myTitle.add(new LabelField("The second line."));
// Set the Title
setTitle(myTitle);
}
}
I want to create a popup screen in BlackBerry like the screen appear on long click (see the picture)
My screen contain 3 items
image description
image description
image description
Can any one help me by an example or link to do this popup?
Use the below code and call the GetPopup wherever you want to show the pop up screen
final class Getpopup extends PopupScreen
{
EditField edf;
AutoTextEditField edf1;
HorizontalFieldManager hfm;
public Getpopup()
{
super( new VerticalFieldManager());
LabelField lf = new LabelField("Contact Info", LabelField.FIELD_HCENTER);
SeparatorField sf = new SeparatorField();
edf1= new AutoTextEditField("Name:","" ,20,EditField.NO_NEWLINE);
edf = new EditField("Number:",ThirdScreen.get3);
edf.setEditable(false);
VerticalFieldManager vfm =new VerticalFieldManager(VerticalFieldManager.FIELD_HCENTER);
hfm=new HorizontalFieldManager(HorizontalFieldManager.FIELD_HCENTER);
ButtonField bf1 = new ButtonField("Save", ButtonField.FIELD_HCENTER);
ButtonField bf2 = new ButtonField("Cancel", ButtonField.FIELD_HCENTER);
hfm.add(bf1);
hfm.add(bf2);
vfm.add(lf);
vfm.add(sf);
vfm.add(edf1);
vfm.add(edf);
vfm.add(hfm);
add(vfm);
}
}
Find the code here to create creating-borderless-transparent-popup screen in blackberry
If your looking for custmizing the Buttons as appeared in image then visit custom-image-buttonfield-in-blackberry
You have to make use of GridFieldManager.java for the layout you have used, Also you can customize your own layout.
Create a PopupDialog class which extends Dialog and then in the constructor, add the Buttons. If you would like your buttons to look like the above image, extend a field or button field and in paint method, draw the button and then the button text below the button. Add this custom button control in the PopupDialog.