Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Layout Problems with GWT Native Components

    I've got a GWT TabPanel with width=400, it contains a SmartClient VStack in a tab. That VStack is set to 100% width. I'd expect 100% to be 100% of it's containing component (i.e. 400px), but it appears to be 100% of the entire browser screen width.

    In this example, you can see how the first tab is pushed out to an excessive width by the VStack inside it. If you switch to the second tab (which only contains a native GWT HTML component) the width is 500 pixels as expected.

    Suprisingly, if we the VStack width to 1, same issue. I dug in with FireBug - it's setting the VStack DIV to have an inline style 'width: 1379px' (or however wide the browser window is) when I would have expected 'width: 1px' or 'width: 100%'.


    Code:
    public void onModuleLoad() {
        	
            DecoratedTabPanel tabPanel = new DecoratedTabPanel();
            tabPanel.setWidth("400");
            tabPanel.setAnimationEnabled(true);
    
            VStack stack = new VStack(10);
            stack.setWidth100();
            tabPanel.add(stack, "My Tab Category");
            
            tabPanel.add(new HTML("foo"), "My Other Tab");
            
            tabPanel.selectTab(0);
            RootPanel.get().add(tabPanel);
        }

    #2
    Layout Problems

    Did you ever figure this out? I'm having the same problem - I want to embed a TreeGrid in a standard GWT panel and have it fill up 100% of the panel. I would settle for smartgwt not setting width and height at all so I could do it in CSS, but it seems to set height and width on the style element itself which makes it impossible to override. I've come close to working around it by manually setting the width/height to the parent offsetwidth/height but scroll bars are still not behaving quite right.

    Thanks,
    Brian

    Comment


      #3
      Brian - I'm trying to work around it and I currently have a mix of GWT and SC components that comes close. Will post here if I get it perfect.

      Here's one more example of a GWT+SCGWT layout problem, hopefully this is helpful to the devs:

      In this case I use a DynamicForm, same behavior (way too wide) but especially notice that the SelectItem's hint is rendered in a very narrow panel that forces the text to take up 5 lines.

      Code:
      public void onModuleLoad() {
          	
              DecoratedTabPanel tabPanel = new DecoratedTabPanel();
              tabPanel.setWidth("400");
              tabPanel.setAnimationEnabled(true);
              
              final DynamicForm form = new DynamicForm();
              form.setWidth100();
              SelectItem selectItem = new SelectItem();
              selectItem.setTitle("Country");
              selectItem.setHint("Pick a country from the drop-down list");
              LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
              valueMap.put("US", "<b>United States</b>");
              valueMap.put("CH", "China");
              valueMap.put("JA", "<b>Japan</b>");
              valueMap.put("IN", "India");
              selectItem.setValueMap(valueMap);
              form.setItems(selectItem);
      
              tabPanel.add(form, "My Tab Category");
              
              tabPanel.add(new HTML("foo"), "My Other Tab");
              
              tabPanel.selectTab(0);
              RootPanel.get().add(tabPanel);
          }

      Comment


        #4
        Guys, setting width:100% in native CSS wouldn't really solve this problem. Contained components need to know the actual pixel width in order to implement various layout algorithms that go beyond CSS.

        The issue here is that GWT's containers do not provide an API similar to Canvas.getInnerWidth(), which children can use to find out the available space to draw themselves in, and hence recursively lay out out their own children. Nor do they fire events when they are resized, or when the available width changes for various reasons (eg scrollbar(s) introduced, or CSS style changes add borders and hence reduce space).

        A lot of parent<->child coordination and signaling is required to really create an extensible pixel-perfect layout system. SmartClient has implemented all the necessary hooks to allow a third-party widget to be embedded inside a Canvas and participate in a precise layout, but GWT is not there yet.

        If you absolutely must place a SmartGWT interface inside a GWT container and you want it to fill the container, the best approach is to listen for the window-level resize event and run your own layout calculations that ultimately call resizeTo() on your topmost SmartGWT widget. All SmartGWT widgets nested under that topmost widget will then handle layout normally.

        Comment


          #5
          I will give this a shot, thanks. If I get it working perfectly I'll post back here.

          Comment


            #6
            As Iso suggested - this can be done. A very simple example is below in case anyone else needs it. This uses hardcoded width/height because the math you do will be specific to your own layout.

            Code:
            		Window.addWindowResizeListener(new WindowResizeListener() {
            
            			public void onWindowResized(int width, int height) {
            
            				fitCanvas.resizeTo(900, 400);
            			}
            
            		});
            That will get you resized as the main window is resized. You also will need to do a resizeTo() at the very end of your onModuleLoad to handle the initial display case.

            If the GWT component that's acting as the container is itself resizeable, you will also need to catch that resize event and do the same logic.

            After doing this I still have one nagging rendering issue. I'll distill that down to a simple case and post about it separately.

            Comment


              #7
              Hi scoobydoo,

              Did you get to the bottom of the "narrow hints" problem in post #3? I am having a similar problem (http://forums.smartclient.com/showthread.php?t=3334). I don't think that resizeTo can resolve that, as it is a problem with my DynamicForm, which is nested inside other SmartGWT components, the outermost of which is in a GWT PopupPanel.

              Is that your nagging rendering issue?

              Thanks,

              Andrew

              Comment


                #8
                Originally posted by Isomorphic
                If you absolutely must place a SmartGWT interface inside a GWT container and you want it to fill the container, the best approach is to listen for the window-level resize event and run your own layout calculations that ultimately call resizeTo() on your topmost SmartGWT widget. All SmartGWT widgets nested under that topmost widget will then handle layout normally.
                what about doing layout in HTML page ? i've a DIV in HTML page with absolute positioning and exact size. i've placed a SmartGWT (VStack) component inside it. similar to above, 100% width and heigth occupied the whole page instead of the div.

                so is WindowResizeListener the only solution to this case also ?

                Comment


                  #9
                  @raft the WindowResizeListener approach will work in this case as well, but there may be simpler approaches depending on your requirements. For example, if you just place a SmartGWT interface into an HTML layout and give it, eg, 70% size, the SmartGWT layout will take up 70% of the window and some HTML layouts will correctly flow around it.

                  [note: this assumes position:"relative" has been set on the outermost SmartGWT component (and only the outermost component)]

                  Comment


                    #10
                    ok but...

                    There is something i didn't understand.
                    If in my application I had used ONLY SmartGWT component from the lower level to the upper one, in a full dynamic approach (so the body in my html application file is empty) would have been possible to set up correctly the components' size from CSS using percentages, absolute dimensions and similar?
                    Thank you very much.

                    Originally posted by Isomorphic
                    Guys, setting width:100% in native CSS wouldn't really solve this problem. Contained components need to know the actual pixel width in order to implement various layout algorithms that go beyond CSS.

                    The issue here is that GWT's containers do not provide an API similar to Canvas.getInnerWidth(), which children can use to find out the available space to draw themselves in, and hence recursively lay out out their own children. Nor do they fire events when they are resized, or when the available width changes for various reasons (eg scrollbar(s) introduced, or CSS style changes add borders and hence reduce space).

                    A lot of parent<->child coordination and signaling is required to really create an extensible pixel-perfect layout system. SmartClient has implemented all the necessary hooks to allow a third-party widget to be embedded inside a Canvas and participate in a precise layout, but GWT is not there yet.

                    If you absolutely must place a SmartGWT interface inside a GWT container and you want it to fill the container, the best approach is to listen for the window-level resize event and run your own layout calculations that ultimately call resizeTo() on your topmost SmartGWT widget. All SmartGWT widgets nested under that topmost widget will then handle layout normally.
                    Last edited by j3st3r; 10 Feb 2010, 02:57.

                    Comment

                    Working...
                    X