Vaadin refuses to align image in a HorizontalLayout - image

I'm using Vaadin 8 and I have a HorizontalLayout at the very top of the page. It's in a VeritcalLayout which is the main content of the UI.
Something like:
UI
VerticalLayout (margin=false, spacing=false)
HorizontalLayout (margin=false, spacing=false)
So you would expect everything to align to the edges of the browser viewport. I also have set default component alignment on everything to TOP LEFT.
Now, I want to put an image in the upper-right of that HorizontalLayout. The image aligns to the right of the screen as expected but the top of the image has about 30-40 pixels of padding that I cannot get rid of.
Imagine the black box as the logo I am using:
My UI init:
#SpringUI
#Theme("valo")
#PushStateNavigation
public class CustomUI extends UI implements ViewDisplay {
private static final long serialVersionUID = -3026091945679596519L;
#Autowired
private SpringViewProvider viewProvider;
#Autowired
private SpringNavigator navigator;
#Override
protected void init(VaadinRequest vaadinRequest) {
setSizeFull();
final VerticalLayout root = new VerticalLayout();
root.setMargin(false);
root.setSpacing(false);
root.setSizeFull();
setContent(root);
navigator.init(this, root);
}
#Override
public void showView(View view) {
this.setContent((Component) view);
}
My HorizontalLayout:
HorizontalLayout layout = new HorizontalLayout();
layout.setMargin(false);
layout.setSpacing(false);
layout.setHeight(64, Unit.PIXELS);
layout.setWidth("100%");
String basePath = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath();
FileResource logo = new FileResource(new File(basePath + "/WEB-INF/images/logo.PNG"));
Image logoImg = new Image("", logo);
layout.addComponent(logoImg);
layout.setComponentAlignment(logoImg, Alignment.TOP_RIGHT);
The image is 64 pixels tall. The HorizontalLayout is also 64 pixels tall according to the debugger.
But notice how far off it is on the top.
What am I doing wrong?

just change
Image logoImg = new Image("", logo);
into
Image logoImg = new Image(null, logo);
Components in a HorizontalLayout have their caption on top of the component. If the caption is not null, i.e. it is empty it does take the aforementioned 30-40 pixels.

For me it looks like it looks like that UI itself still has margin. So you need to disable in.
#Override
protected void init(VaadinRequest vaadinRequest) {
setSizeFull();
setMargin(false); // this was missing
final VerticalLayout root = new VerticalLayout();
root.setMargin(false);
root.setSpacing(false);
...
}

Related

Charm 4.0.0 PopupView shows up only once

I have a set of Controls which use PopupView.
Since the update to Charm 4.0.0, they show some weird behaviour.
When I selected a Node contained in the PopupView, the PopupView used to get closed. Now the PopupView gets closed but immediately shows up again. Furthermore as soon as I click outside the PopupView it gets closed, but I am not able to show it again.
I've tested it with the example from the Gluon javadoc and experienced the same behaviour regarding the second issue:
public class MyApp extends MobileApplication{
private Button button;
private PopupView popupView;
#Override
public void init() {
addViewFactory(HOME_VIEW, () -> {
button = new Button("Click");
button.setOnAction(event -> popupView.show());
popupView = new PopupView(button);
VBox vBox = new VBox();
vBox.getChildren().addAll(new Label("Choice 1"), new Label("Choice 2"), new Label("Choice 3"));
vBox.setSpacing(5);
popupView.setContent(vBox);
return new View(button) {
#Override
protected void updateAppBar(AppBar appBar) {
appBar.setTitleText("PopupView");
}
};
});
}
}
Thanks for reporting. I've filed an issue so it get fixed as soon as possible.
In the meantime, a workaround for the PopupView can be this:
PopupView popupView = new PopupView(button) {
private final GlassPane glassPane = MobileApplication.getInstance().getGlassPane();
{
this.setOnMouseReleased(e -> this.hide());
}
#Override public void show() {
// before showing add the glassPane (issue #2):
this.mobileLayoutPaneProperty().set(glassPane);
super.show();
}
#Override public void hide() {
// when hiding don't show again (issue #1):
setShowing(false);
super.hide();
}
};

Showing the uploaded image in Vaadin with EasyUploads

I'm trying to use EasyUploads-addon for Vaadin, but can't get the image shown.
When I click addon's "Choose File"-button, it will ask me to open an file. I choose some .png -file from my images and addon shows the information of the picture beneath it.
Then I press my "Upload"-button, which is currently needed just to show the uploaded image at first.
private void showUploadedImage() {
Object value = upload.getValue();
byte[] data = (byte[]) value;
StreamResource resource = new StreamResource(
new StreamResource.StreamSource() {
private static final long serialVersionUID = 1L;
#Override
public InputStream getStream() {
return new ByteArrayInputStream(data);
}
}, "filename.png");
image.setVisible(true);
image.setCaption("Uploaded image");
image.setSource(resource);
}
upload = EasyUpload's component which is used to choose file
image = Embedded component that I have drawn with the designer to my layout.
But when I look the page with browser the image is not shown. The image is just shown as there is no image at all, just caption will be shown.
HTML-code of the image from the page's source:
<img src="null">
This might be really trivial case, but all the examples that I found was over 3-4 years old and didn't look helpful.
Can someone tell me, how it should be done?
You need to call a setter on UploadField class:
uploadField.setFieldType(FieldType.BYTE_ARRAY);
Working SSCCE:
#Override
protected void init(VaadinRequest request) {
setContent(layout);
final UploadField uploadField = new UploadField();
uploadField.setAcceptFilter(".png");
uploadField.setFieldType(FieldType.BYTE_ARRAY);
uploadField.addListener(new Listener(){
#Override
public void componentEvent(Event event)
{
showUploadedImage(uploadField);
}
});
layout.addComponent(uploadField);
layout.addComponent(image);
}
private void showUploadedImage(UploadField upload) {
Object value = upload.getValue();
final byte[] data = (byte[]) value;
StreamResource resource = new StreamResource(
new StreamResource.StreamSource() {
#Override
public InputStream getStream() {
return new ByteArrayInputStream(data);
}
}, "filename.png");
image.setSource(resource);
}
Produces (after choosing a .png file):
Of course you may want to change type of uploadField listener to more specific one.
Tested on Java 8, Vaadin 7.4.1, Eclipse Luna.

About TextField with a small icon

I want to code a TextField component with icon.
So the behavior is as follow:
If the TextField contains an empty string, I use "lens.png".
Otherwise, i use "cross.png".
using the JavaFX Scene Builder, I added a TextFiled and an ImageView in the stack pane.
My code is the following:
#FXML
private TextField textSearch;
#FXML
private ImageView imageView;
final Image lensIcon = new Image("/issue/images/lens.png");
final Image crossIcon = new Image("/issue/images/cross.png");
//initialize () method
textSearch.textProperty().addListener(obs -> {
final String text = textSearch.getText();
Image icon = (text==null || text.isEmpty()) ? lensIcon : crossIcon;
imageView.setImage(icon);
imageView.setMouseTransparent(icon == lensIcon);
}
);
imageView.setOnMouseClicked(evt -> textSearch.setText(null));
my issue is the following:
How to prevent writing caracters below the icon (ImageView). the following figure illustrate my issue.
ControlsFX is an JavaFX API that supplies a ton of advanced controls UI that didn't come with JavaFX out of the box.
ControlsFX - http://fxexperience.com/controlsfx/
FontAwesomeFX supplies hundreds of icons (such as a cross in your case above)
FontAwesomeFX - https://bitbucket.org/Jerady/fontawesomefx/downloads/
Here is a demo solution to your problem after importing both these fantastic APIs
public class TextFields_Demo extends Application {
private Parent createContent() {
Pane root = new Pane();
CustomTextField customTextField = new CustomTextField();
FontAwesomeIconView icon = new FontAwesomeIconView(FontAwesomeIcon.CLOSE);
customTextField.setRight(icon);
root.getChildren().add(customTextField);
return root;
}
#Override
public void start(Stage primaryStage) {
Scene scene = new Scene(createContent());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

JavaFX 2.0 subwindow

How can I display a new window in JavaFX 2.0? For example after button click action.
I want both windows (the main window and the new window) to communicate each other.
Thx for help.
new Stage(new Scene(new Group(new Text(10,10, "my second window")))).show();
Communicating between two windows is similar as for any two objects in Java.
You create new windows by calling new Stage() and show them by stage.show().
Here is an example of creating a new Stage with a checkbox control which modifies text of a label displayed in a different Stage.
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.StackPane;
import javafx.stage.*;
public class SecondStage extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(Stage primaryStage) {
// setup some dymamic data to display.
final String STANDARD_TEXT = "Every Good Boy Deserves Fruit";
final String ALTERNATE_TEXT = "Good Boys Deserve Fruit Always";
final Label label = new Label(STANDARD_TEXT);
// configure the primary stage.
StackPane primaryLayout = new StackPane();
primaryLayout.getChildren().add(label);
primaryLayout.setStyle("-fx-background-color: lightgreen; -fx-padding: 10;");
primaryStage.setScene(new Scene(primaryLayout, 200, 100));
primaryStage.setTitle("Primary Stage");
// configure the secondary stage.
final Stage secondaryStage = new Stage(StageStyle.UTILITY);
CheckBox alternateTextCheck = new CheckBox("Show alternate text");
alternateTextCheck.selectedProperty().addListener(new ChangeListener<Boolean>() {
#Override public void changed(ObservableValue<? extends Boolean> selected, Boolean oldValue, Boolean newValue) {
if (newValue) label.setText(ALTERNATE_TEXT); else label.setText(STANDARD_TEXT);
}
});
StackPane secondaryLayout = new StackPane();
secondaryLayout.getChildren().add(alternateTextCheck);
secondaryLayout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
secondaryStage.setScene(new Scene(secondaryLayout, 200, 100));
secondaryStage.setTitle("Secondary Stage");
// specify stage locations.
secondaryStage.setX(400); secondaryStage.setY(200);
primaryStage.setX(400); primaryStage.setY(350);
// add a trigger to hide the secondary stage when the primary stage is hidden.
// this will cause all stages to be hidden (which will cause the app to terminate).
primaryStage.setOnHidden(new EventHandler<WindowEvent>() {
#Override public void handle(WindowEvent onClosing) {
secondaryStage.hide();
}
});
// show both stages.
primaryStage.show();
secondaryStage.show();
}
}
Inside the button click action you can create a new satge and then a object of the other class you want to display. after that call the start method using the created object.
Stage stage= new Stage();
NewClass nc= new NewClass();
nc.start(stage);
hope this will work!!!

Blackberry - Setting LabelField background color

I want to place several LabelFields with right-aligned text on a MainScreen with an alice blue background. Unfortunately I can't seem to figure out how to make that happen.
The best I can do is set my backround to Color.ALICEBLUE on a MainScreen and place LabelFields on the screen (also with a alice blue background).
public void paint(Graphics graphics) {
graphics.setBackgroundColor(Color.ALICEBLUE);
graphics.clear();
super.paint(graphics);
}
and...
LabelField display = new LabelField("", LabelField.FIELD_RIGHT){
public void paint(Graphics graphics) {
graphics.setColor(Color.DIMGRAY);
graphics.setBackgroundColor(Color.ALICEBLUE);
graphics.clear();
super.paint(graphics);
}
};
Overriding the MainScreen paint routine gives me my alice blue background, but overriding the LabelFields' paint routines does not seem to be adequate. The result is a white row, with a alice blue background behind the label text only. Adding USE_ALL_WIDTH corrects the background issue, but I can't right align with USE_ALL_WIDTH.
Does anyone know a work around for this?
In versions <= 4.5 you can create VerticalFieldManager with overrided paint():
class BGManager extends VerticalFieldManager {
public BGManager() {
super(USE_ALL_HEIGHT|USE_ALL_WIDTH);
}
public void paint(Graphics graphics)
{
graphics.setBackgroundColor(Color.DARKRED);
graphics.clear();
super.paint(graphics);
}
}
Then use it on youre screen adding simple LabelField to it:
class Scr extends MainScreen {
BGManager manager = new BGManager();
public Scr() {
super();
add(manager);
manager.add(new LabelField("Hello!", FIELD_RIGHT));
manager.add(new LabelField("This is a test", FIELD_RIGHT));
}
}
In versions >= 4.6 you can use setBackgroud() method for default screen manager:
class Scr extends MainScreen {
public Scr() {
super();
VerticalFieldManager manager =
(VerticalFieldManager)getMainManager();
manager.setBackground(
BackgroundFactory.createSolidBackground(
Color.DARKRED));
manager.add(new LabelField("Hello!", FIELD_RIGHT));
manager.add(new LabelField("This is a test", FIELD_RIGHT));
}
}
See BB KB DB-00131 - How to - Change the background color of a screen
Use
new LabelField("",LabelField.USE_ALL_WIDTH | DrawStyle.RIGHT);
without overriding the paint method of the LabelField.

Resources