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.
Related
I created a class named "Footer" having just a Label. I also have a few views like loginview, orderview). And I would like to add that footer to every view. This is my code until now.
#ParentLayout(OrderView.class)
public class footer extends VerticalLayout implements RouterLayout {
public footer() {
add(new Span("This text should be underneath the page in the views"));
}
}
Underneath you have my orederview where I want to see that text from the footerclass.
#Route("order")
public class OrderView extends VerticalLayout implements RouterLayout {
public OrderView (){
// What am I supposed to code here to get that text from Footerclass.
}
}
I would like to know what I am missing.
Thanks for the help.
Your usage of the annotations is wrong. Here is super simplified outline how you should create MainLayout and route that defines a component that is shown in the mainlayout when navigated to that route.
public class MainLayout extends VerticalLayout implements RouterLayout {
private Div childWrapper = new Div();
public void MainLayout() {
setSizeFull();
Span header = new Span("This text should be above the page in the views");
Span footer = new Span("This text should be underneath the page in the views");
add(header);
addAndExpand(childWrapper)
add(footer);
}
#Override
public void showRouterLayoutContent(HasElement content) {
childWrapper.getElement().appendChild(content.getElement());
}
}
#Route(value = "order", layout = MainLayout.class)
public class OrderView extends VerticalLayout {
public OrderView (){
}
}
There is video tutorial about Router concept on vaadin.com page that explains this in detail.
Instead of
new Label("This text should be underneath the page in the views");
try
add(new Span("This text should be underneath the page in the views"));
In Vaadin Flow the Label component is meant to be used coupled with another component, not for adding stand-alone text like in Vaadin 8 and older. Also, every component needs to be added to the layout before they can become visible, just creating them isn't enough.
Unfortunately LoginOverlay doesn't have API for adding extra components within it, but there is an open ticket about the feature that you can add thumbs up on to add more weight to it, and there's also a workaround presented in the comments: https://github.com/vaadin/web-components/issues/626
I'm having issues with my UI in vaadin at the moment. I have my views connected with RouterLayout like this:
-AppView (the main UI) | url: /
--OperationsView (a nested layout inside a container in AppView) | url: /operations
---Operation1View (a nested layout inside a container in OperationsView) | url: /operation1 <-
This isn't working
My declarations before any class are:
AppView declaration
#Route(value = AppView.ROUTE)
OperationsView declaration
#Route(value = OperationsView.ROUTE, layout = AppView.class)
Operation1View declaration
#Route(value = Operation1View.ROUTE, layout = OperationsView.class)
The problem is the third layout doesn't display correctly. It takes the whole page when accesed and mess up everything in the UI when going to another page. Shouldn't the url be: /operations/operation1 and not /operation1? However I can't get it to work correctly. Am I missing something? Or having 3 nested layouts is not possible with vaadin?
A possible solution (?): Should I dismiss the third nested layout and add methods in the second layout to remove the contents in the container and display the items I want? I really don't care about url navigation in this one. This is the last thing I can come up with.
Thanks in advance
Or having 3 nested layouts is not possible with vaadin?
It's possible. But are you implementing a RouterLayoutin both OperationsView and AppView classes?
Take a look into example here: Multiple parent layouts with #ParentLayout. It has a set-up pretty close to yours.
public class MainLayout extends Div implements RouterLayout {
}
#ParentLayout(MainLayout.class)
public class MenuBar extends Div implements RouterLayout {
public MenuBar() {
addMenuElement(TutorialView.class, "Tutorial");
addMenuElement(IconsView.class, "Icons");
}
private void addMenuElement(Class<? extends Component> navigationTarget,
String name) {
// implementation omitted
}
}
#Route(value = "tutorial", layout = MenuBar.class)
public class TutorialView extends Div {
}
#Route(value="icons", layout = MenuBar.class)
public class IconsView extends Div {
}
Shouldn't the url be: /operations/operation1 and not /operation1?
No, as in your #Router annotation you have specified that it's operation1. By specifying a layout you are defining the DOM structure, not the navigation route.From docs :
Sets the parent component for the route target component.When navigating between components that use the same layout, the same component instance is reused. Default layout target is the UI, but the layout should not be a custom UI as UI is a special class used to know where the route stack ends and no parent layouts should be involved.
All layout stacks will be appended to the UI as it represents the Body element.
BUT If you want it to be operation\operation1, you should use a #RoutePrefix instead ParentLayout Route Control
It takes the whole page when accesed and mess up everything in the UI when going to another page
Could you show a screenshot or add some details how it messes up?
Edit:
It's actually turned out to be harder to implement than I anticipated, but this seems to work:
MainView.java
#Route("")
public class MainView extends VerticalLayout implements RouterLayout {
....
OperationsView.java
//This is needed if you want "operations" to be accessible on its own
#Route(value = "operations",layout = MainView.class)
#ParentLayout(MainView.class)
public class OperationsView extends VerticalLayout implements RouterLayout {
Div content=new Div();
public OperationsView(){
System.out.println("operations view");
add(new Label("operations view"));
add(content);
}
}
Operation1View.java
#Route(value="operation1",layout = OperationsView.class)
#RoutePrefix("operations")
public class Operation1View extends VerticalLayout {
public Operation1View(){
add(new Label("Operations view"));
}
}
I want include Grid in FramedPanel and using gxt dnd.
But if I add FramedPanel in DragSource:
DragSource source = new DragSource(framedPanel) {
#Override
protected void onDragStart(DndDragStartEvent event) {
super.onDragStart(event);
event.setData(framedPanel);
}
};
DnD works when I click and hold on Grid.
How I can do to DnD only worked on the header of FramedPanel.
Consider using Draggable instead of DragSource, then use the constructor that takes two arguments. This way you can specify the header as the 'handle' argument.
Draggable draggable = new Draggable(framedPanel, framedPanel.getHeader());
//assuming GXT 3, just guessing from your post
draggable.addDragStartHandler(new DragStartHandler() {
public void onDragStart(DragStartEvent event) {
//...
}
});
If you must use DragSource, subclass it to replace the Draggable instance, and create a new instance as specified above, plus making the changes found in the existing DragSource constructor.
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 am rendering some images that are layered in a JEditorPane. I've read that JEditorPane is pretty rocky at best, however I am hoping that this is an issue with either my HTML code or something else. Here's how my content looks in the browser:
And how it looks in a JScrollBar(JEditorPane):
The HTML code: http://pastebin.com/EixG3WLH
The Java code:
File f = new File("index.html");
JEditorPane jep = new JEditorPane(f.toURI().toURL());
JScrollPane sp = new JScrollPane(jep);
JFrame frame = new JFrame();
frame.add(sp);
jep.setEditable(false);
frame.setVisible(true);
frame.setSize(500, 500);
frame.setTitle(wpj.getParse().getTitle());
I'd really rather not use FlyingSaucer if this issue can be resolved in a JEditorPane!
You can do it... but it's not really simple... because JEditorPane doesn't have CSS absolute positioning... so, you must first at all, recognize if some element had the position:absolute or position:fixed attribute extending the ViewFactory, something like:
public class ExtendedHTMLEditorKit extends HTMLEditorKit{
//.... other code here
public class MyHTMLFactory extends HTMLFactory{
//other code here
#Override
public View create(Element elem) {
if (isLayered(elem)){ //it means, it has position attribute
return new PositionedView(elem);
}
else
return super.create(elem);
}
boolean isLayered(Element elem){
SimpleAttributeSet sas = new SimpleAttributeSet(elem);
StyleSheet styles = (HTMLDocument elem.getDocument).getStyleSheet();
Tag tag = element.getAttributes().getAttribute(AttributeSet.NameAttribute);
sas.addAttributes(styleSheet.getRule(tag, element));
return sas.isDefined("position")
&& !sas.getAttribute("position").toString().equalsIgnorecase("static");
}
}
}
In this case, we need then to build a correct view for your element... I don't know if you're only positioning images (in this case, it could be simple) or a lot of things... I can see on your code, you're using divs...
Let me explain more or less what I do: I've created a ComponentView, and returning as a component a new JEditorPane, where I put the innerCode of the original element... and after that, move it on correct position of parent editor...
To synchronize this is really dificult to allow edit, but if you only whant to use them to display, it must be more simple...
ok.. the view must be like:
public class PositionedView extends ComponentView{
private JEditorPane view;
private JEditorPane parent;
#Override
public Component createComponent(){
if (view == null){
view = new JEditorPane();
}
String innerText = dumpInnerText(getElement());
view.setText(innerText);
view.setLocation(getAbsoluteX(), getAbsoluteY());
parent.add(view);
}
#Override
public void setParent(View parent) {
if (parent != null) {
java.awt.Container host = parent.getContainer();
if (host != null && host instanceof JEditorPane) {
parent = (JEditorPane) host;
}
}
super.setParent(parent);
}
protected int getAbsoluteX() {
//search for the attribute left or right and calculate the position over parent
}
protected int getAbsoluteY(){
//search for the attribute top or bottom and calculate the position over parent
}
protected String dumpInnerText(Element element){
//there are several ways to do it, I used my own reader/writer,
//because I've need add special tags support...
}
}
I hope this helps you... Ah! there are another thing: if you do this, you must secure your view is not opaque, and it means, all the view elements, on the other case, you will have a blank rect for your elements.
Another thing, you maybe need to check for the correct dimension of the view... do as getAbsoluteX / getAbsoluteY to obtain width / height attributes.
JEditorPane is not so good with CSS absolute positioning. I think you are trying to achieve more with JEditorPane than it is capable of delivering.