I want to set a CustomScrollPanel to height 100%; What I tried is to get the CustomScrollPanel to height 100% but it does not work that way. Here is want I tried.
public class MyScrollPanel extends Composite implements HasWidgets {
private ResizeLayoutPanel resizeLayoutPanel;
private CustomScrollPanel customScrollPanel;
public MyScrollPanel() {
resizeLayoutPanel = new ResizeLayoutPanel();
resizeLayoutPanel.setStyleName(resources.css().resizeLayoutPanel());
customScrollPanel = new CustomScrollPanel();
customScrollPanel.addStyleName(resources.css().customScrollPanel());
resizeLayoutPanel.add(customScrollPanel);
initWidget(resizeLayoutPanel);
}
My css:
.resizeLayoutPanel {
height: 100%;
background-color: yellow;
}
How do I get the CustomScrollPanel to height 100%?
height:100% will not work unless the parent div has a fixed height like height:500px.
The best way would be to calculate the height of the window / parent container and the assigning that to your div element, with a resize condition at runtime.
ScrollPanel implements RequiresResize, which means it gets its size from its parent widget, as long as the parent widget implements ProvidesResize. If the parent widget takes 100% of the space, vertically, then the ScrollPanel will take the same space too.
Related
I have an Entity which is persisted and which provides data for rows in a Vaadin Grid. This part works.
I now want to display a boolean value as an Image. For this I added a getter to the entity. This part only works when the record has been persisted to the database recently, which I think means that the getter is persisted, which is not desired. For rows persisted to the database before introduction of the getter, the field stays blank in the vaadin grid due to enabledIcon property returning something empty.
I tried to disable this behavior by adding a #Transient annotation, but for some reason then the eureka client has errors, and it also does not help with the empty fields.
I am considering creating a new wrapper class by composition instead of inheritance, but then I have to create all these getters and setters manually which seems to me to be bad design.
Any answer is welcome, even the ones which tell me to go with a wrapper class by composition.
package com.xxx.bpspkpibpcheck.model;
import javax.persistence.Entity;
//import javax.persistence.Transient;
import com.xxx.common.model.KPI;
import com.vaadin.server.ThemeResource;
#Entity
public class KPIBusiness extends KPI {
private static final String IMAGES = "images/";
private static final String IMAGE_STATUS_RED = IMAGES + "LED_red_24.png";
private static final String IMAGE_STATUS_GREEN = IMAGES + "LED_green_24.png";
private static final String IMAGE_STATUS_GRAY = IMAGES + "LED_gray_24.png";
private ThemeResource redStatus = new ThemeResource(IMAGE_STATUS_RED);
private ThemeResource greenStatus = new ThemeResource(IMAGE_STATUS_GREEN);
private ThemeResource grayStatus = new ThemeResource(IMAGE_STATUS_GRAY);
//#Transient
//ThemeResource enabledIcon = greenStatus;
//#Transient
public ThemeResource getEnabledIcon()
{
return getEnabled() != 0 ? greenStatus : grayStatus;
}
}
I might have missed something important here but here is my approach to this one.
To me the problems seems to be that in this case model - your entity - and view / presenter stuff have been mixed in your entity class. And you usually do not want to persist view related stuff.
You should separate this image stuff out of your entity and add the image column as generated column to the grid.
See this as an example: How to add a generated column to Vaadin 8 Grid?
UPDATE: provided example link is not about component column which is needed here so as an example:
Add a component column:
grid.addComponentColumn(statusProvider).setCaption("Status").setId("status");
where statusProvider is like:
ValueProvider<GridEntity, Layout> statusProvider = gridEntity -> {
AbsoluteLayout al = new AbsoluteLayout();
al.setSizeUndefined();
al.addStyleName("status");
String styleName = (gridEntity.isStatusOk()) ? "green" : "red";
al.addStyleName(styleName);
return al;
};
So in my version the "traffic lights" are implemented by cascading css stuff with addStyleName(...) (using the default mytheme.scss) but of course the LEDs images can alos be used either in css or as you originally planned.
.status {
width: 30px;
height: 30px;
border-radius: 15px;
margin: 0;
padding: 0;
}
.green {
background-color: green;
}
.red {
background-color: red;
}
Given the following vaading example app:
package net.kerba.vaadin7interface;
import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.*;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
/**
* Created by IntelliJ IDEA.
* Date: 19.11.13
* Time: 20:48
*/
#Theme("runo")
public class MainUi extends UI {
#Override
protected void init(VaadinRequest request) {
GridLayout main = new GridLayout();
main.setSizeFull();
main.setMargin(false);
Panel panel = new Panel("Working area");
main.addComponent(panel, 0, 0);
// magic goes in 2 lines below
panel.setWidth("500px");
panel.setHeight("300px");
panel.setContent(new Label("foobar");", ContentMode.PREFORMATTED));
main.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
setContent(main);
}
#WebServlet(name = "vaadinServlet",
urlPatterns = {"/app/*", "/VAADIN/*"},
asyncSupported = false,
initParams = {#WebInitParam(
name = "widgetset",
value = "com.vaadin.DefaultWidgetSet"
)}
)
#VaadinServletConfiguration(productionMode = false, ui = MainUi.class)
public static class Servlet extends VaadinServlet {
}
}
When I use % for width and height:
panel.setWidth("50%");
panel.setHeight("50%");
I get both scrollbars:
When I use pixels for width and height:
panel.setWidth("500px");
panel.setHeight("300px");
The both scrollbars are gone:
How can I use % for width and height and make Vaadin do not show that scrollbars?
Vaadin 7.1.8
I've found that introducing your own theme by extending e.g. runo or reindeer always pays. Then having this you can declare a class on you panel and set its width/height in CSS rather than in the code. This way it's the browser which sets the size before any JS executes and so it's known before JS that scrollbars are not needed in this case.
It's because with GridLayout writing
main.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
it sets in fact gridlayout-slot in the middle of the screen making it 100% size of your screen and from this 50% is your panel - for me it seems to be a bug...
The workaround would be to use different layout, with VerticalLayout it will work. Or fake grid layout with CustomLayout.
I am not very sure about the solution, but while referring online. I found a couple of links, which I think can help you solve the problem:
Link 1
Link 2
According to which
main.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
makes it to be in the middle of the screen i.e, actually half of the panel defined.
You can go about either creating another panel with different specifications or use a virtual view to work around with this, ie. A Grid Layout that would just be used to format the indents and customize it effectively to your use.
Use HGap, VGap and then set the alignment. Refer this example
Use an entirely different layout completely, some change in the current specification for layout positioning.
I'm trying to use a flowpanel in java gwt but when I add different widgets, the panel adds every widget in a new line, here is how I set the flowPanel
public class Test extends Composite {
public abstract class SomeWidget<T> extends Composite {
...
}
public class SomeStringWidget extends SomeWidget<String> {
...
}
public void setWidget() {
FlowPanel fp = new FlowPanel();
fp.setWidth("100%");
fp.add(new SomeStringWidget());
fp.add(new SomeStringWidget());
...
}
}
Why is every Widget set in a new line and not, as the flowpanel should, add the widgets in a line till there is no more space and then add them in a new line??
Flow Panel generates a DIV-Element with the Style GWT-FlowPanel. If you want that you inner Widgets are inline make the CSS of the inner Widgets with the following CSS:
.SomeStringWidget {
display: inline;
}
or
.SomeStringWidget {
display: inline-block;
}
or
.SomeStringWidget {
float: left;
}
And in your widget set the CSS Class .SomeStringWidget in the constuctor.
public SomeStringWidget {
this.setStyleName("SomeStringWidget");
}
I was facing same issue and assigned style to FlowPanel widget to align widgets in a line. This will solve your problem.
FlowPanel fp = new FlowPanel();
fp.setStyleName("flowPanel_inline");
style.css
.flowPanel_inline
{
display:inline;
}
Also you have to set this same style in added elements also.
If your SomeStringWidget is a Label, then it will always be a new line. If you don't want the newline, use InlineLabel.
I have little issue with CssResource in GWT. I want to change styles of AbsolutePanel and label, but it doestnt run. When I add style class with setStyleName method, nothing is happend.
In this snippet of code I use a resource :
public CustommerView() {
MyResource cssResource = GWT.create(MyResource.class);
MyCss myCss = cssResource.css();
AbsolutePanel basePanel = new AbsolutePanel();
initWidget(basePanel);
basePanel.setStyleName(myCss.rootPanel());
Label label = new Label();
label.setText("Im label");
label.setStyleName(myCss.label());
basePanel.add(label);
}
This is my interface which extends CssResource:
public interface MyCss extends CssResource {
/**
* Method for return command button class name
* #return command button class name
*/
public String rootPanel();
public String label();
}
This is my css file, which is next to MyCss interface on filesystem :
.rootPanel {
position:absolute !important;
top:0px;
left:0px;
background-color:yellow !important;
height: 20px !important;
width: 18px !important;
}
.label {
color:red;
}
Custommer view is GWT Composite. When I want to move on view, i call simply RootPanel.get("mainArea").add(view.asWidget) in presenter. mainArea is div element.
When I pasted css class in css file in web inf, everything run ok. Can someone give me the point how to solve this issue? Thanks.
The ensureInjected() call is missing.
I'm looking for a place to hook some code to programmatically create, size and position a JPanel after the application has finished loading.
I'm just starting with Java. I'm using NetBeans 6.5.1 with jdk1.6.0_13. I've used the new project wizard to create a basic Java/Swing desktop application. This is a SingleFrameApplication that uses a FrameView with a central main JPanel where all the UI elements are placed.
I first tried my code in the FrameView constructor but when I try to arrange my JPanel based on the bounding rectangle of one of the design time controls I added to the UI, that control has not yet finished being positioned and sized so I'm getting all zeros for the coordinates.
I've verified my code works as expected by calling it from a click event after the application has loaded so my problem is finding a way to know when everything is finished being sized and arranged.
I also tried the componentShown event from the main JPanel but I later read that is only fired if setVisible is explicitly called which apparently doesn't happen during normal application startup.
Can anyone provide some pointers? Thanks.
Update:
In addition to what I mention in my answer below, I also read about the Application.ready() method. This would also be a point in time of interest for knowing when the UI part of an application is finished doing everything it needs to do. Communicating to my view from the application seemed a bit messy though.
The solution I went with was actually a combination of the answers from Charles Marin and JRL (I upvoted both of your answers for credit, thanks).
I had my FrameView class implement WindowListener.
...
public class MyView extends FrameView implements WindowListener
...
and in my FrameView constructor I added a listener to the application's main frame.
...
getFrame().addWindowListener((WindowListener) this);
...
Then in my implementation of windowActivated I could call the code I had to arrange and size a control on the main JPanel based on the location and size of other controls.
public void windowActivated(WindowEvent e)
{
// The application should now be finished doing its startup stuff.
// Position and size a control based on other UI controls here
}
I think you want WindowActivated. Have a look at this part of the tutorial.
I'd try using getFrame().isValid()
I assume this is the WYSIWYG editor thing. I'm looking at NetBeans 6.1, so your experiences may vary.
The traditional way to layout Swing components is by using a LayoutManager (or LayoutManager2). According to the NetBeans help, the visual editor supports these so long as they don't require support for constraints.
The procedure goes something like this:
Create a new JavaBean and have it implement LayoutManager (a BeanInfo is required too for palette support - you can create one by right-clicking the bean class)
Build the project
Right-click the bean and choose Tools > Add to Palette... and add it
Right-click the panel for which you want to set the layout and select Set Layout > Your Bean Name
You may find the design-time experience somewhat lacking.
A sample layout implementation:
public class StepLayoutBean extends Object implements Serializable, LayoutManager {
public void addLayoutComponent(String name, Component component) {
}
public void layoutContainer(Container container) {
Dimension space = container.getSize();
int xoffset = 0;
int yoffset = 0;
for (Component kid : container.getComponents()) {
Dimension prefSize = kid.getPreferredSize();
if (prefSize.width + xoffset > space.width) {
xoffset = 0;
}
Rectangle bounds = new Rectangle(xoffset, yoffset, prefSize.width, prefSize.height);
kid.setBounds(bounds);
xoffset += prefSize.width;
yoffset += prefSize.height;
}
}
public Dimension minimumLayoutSize(Container container) {
Dimension size = new Dimension();
for (Component kid : container.getComponents()) {
Dimension minSize = kid.getMinimumSize();
size.width = minSize.width > size.width ? minSize.width : size.width;
size.height += minSize.height;
}
return size;
}
public Dimension preferredLayoutSize(Container container) {
Dimension size = new Dimension();
for (Component kid : container.getComponents()) {
Dimension prefSize = kid.getPreferredSize();
size.width += prefSize.width;
size.height += prefSize.height;
}
return size;
}
public void removeLayoutComponent(Component component) {
}
}
If a custom layout doesn't fit the bill, have a look at the event bindings under the component's properties panel - though resizing that way might be a recipe for some kind of recursive event storm.