I have a CTabFolder with one of its CTabItems which may change its contents on a given user action. But I don't know how to force the display once the contents have changed. I get the tab item blank; if I resize the window suddenly everything appears.
I'm not posting the code because I did some wrapping in Scala, but this is basically what I'm doing:
The CTabItem has a ScrolledComposite, set with setControl()
The ScrolledComposite contains a Composite
everything else is under this Composite
When the contents need to be changed, I take the existing CTabItem object, set it to a new ScrolledComposite, with a new Composite, from which hangs the new contents.
Calling redraw() and update() on the CTabFolder object doesn't do it... What should I do?
Thanks
Have you tried calling layout()?
Related
I am using the GridObjectCollection Script from MRTK to display a number of buttons. I am instantiating the buttons dynamically through a script and place them as children of the GridObjectCollection GameObject. Now you can Update the collection through the UpdateCollection() function. Everything works as expected except the following case:
If i want to display a set of different buttons in the same GridObjectCollection, i destroy all children of the collection and instantiate the new buttons as before and call the UpdateCollection() function. But the collection is not updating properly. The old buttons were destroyed and the new added, but the placement is shifted. If i click the UpdateCollection button in inspector, the collection is correctly updated.
Why UpdateCollection() is not working as expected after modifying the content of the collection?
I just fixed the problem. If the collection is updated in the next frame, the update works as expected.
So i am starting a Coroutine and call the update function there.
private IEnumerator InvokeUpdateCollection()
{
yield return null;
gridObjectCollection.UpdateCollection();
}
I'm using setScrollMode(ScrollMode.AUTOY) to enable vertical scrolling when necessary on a VerticalLayoutContainer. However, the scrollbar overlaps the content of the container. The only way around this that I've seen is to call setAdjustForScroll(true). The problem with this is that The panel will then always reserve space for a scrollbar even when one is not present.
Is there a way to tell GXT to only adjust for a scrollbar when one is present? Or perhaps use an event handler (eg ResizeHandler) and check if the scrollbar is currently visible?
Instead of trying to check in a handler if the scrollbar is visible, isn't it just easier to not have the content in the VerticalLayoutContainer?
For example I have:
VerticalLayoutContainer vp = new VerticalLayoutContainer();
vp.setScrollMode(ScrollMode.AUTO);
vp.add(layer1, new VerticalLayoutData(1, -1));
vp.add(layer2, new VerticalLayoutData(1, -1));
vp.add(layer3, new VerticalLayoutData(1, -1));
the layers(1-3) contain the actual content and are different types Ex. VBoxLayoutContainer, Container, VerticalLayoutContainer.
It works for me. I don't think it is relevant but I am adding the vp to a CenterLayoutContainer that is added to the root panel.
I am using GWT 2.4's new DataGrid in a project. I configured the DataGrid with a pagesize of 50.
The available screen is not big enough to display all items and thus a vertical scrollbar is shown (this is actually the main purpose for using a DataGrid in the first place).
I attached a SingleSelectionModel to the DataGrid in order to be able to select items.
This works fine so far.
However I also have another widget with which the user can interact. Based on that user action a item from the DataGrid should be selected.
Sometimes the selected item is not in the visible screen region and the user has to scroll down in the DataGrid to see it.
Is there any way to automatically or manually scroll down, so that the selected item is visible?
I checked the JavaDocs of the DataGrid and found no appropriate method or function for doing that.
Don't know if this works, but you could try to get the row element for the selection and use the scrollIntoView Method.
Example Code:
dataGrid.getRowElement(INDEX_OF_SELECTED_ITEM).scrollIntoView();
The answer above works pretty well, though if the grid is wider than your window and has a horizontal scroll bar, it also scrolls all the way to the right which is pretty annoying. I was able to get it to scroll down and stay scrolled left by getting the first cell in the selected row and then having it scroll that into view.
dataGrid.getRowElement(dataGrid.getVisibleItems().indexOf(object)).getCells().getItem(0).scrollIntoView();
Don't have time to try it out, but DataGrid implements the interface HasRows, and HasRows has, among other things, a method called setVisibleRange. You just need to figure out the row number of the item that you want to focus on, and then set the visible range from that number n to n+50. That way the DataGrid will reset to put that item at the top (or near the top if it is in the last 50 elements of the list backing the DataGrid). Don't forget to redraw your DataGrid.
Have you already looked at this? If so, I'd be surprised that it didn't work.
Oh, and since this is one widget talking to another, you probably have some messaging set up and some message handlers so that when the user interacts with that second widget and "selects" the item, the message fires on the EventBus and a handler for that message fixes up the DataGrid along the lines I've described. I think you'll have to do this wiring yourself.
My solution, a little better:
dataGrid.getRow(model).scrollIntoView();
I got a Out of bounds exception doing the above.
I solved it getting the ScrollPanel in the DataGrid and used .scrollToTop() and so on on the ScrollPanel. However, to access the ScrollPanel in the DataGrid I had to use this comment:
http://code.google.com/p/google-web-toolkit/issues/detail?id=6865
As Kem pointed out, it's annoying the "scrollToRight" effect after the scrollIntoView. After me, Kem's solution gives a better behaviour than the base one as usually the first columns in a table are the more meaningful.
I improved a bit his approach, which scrolls horizontally to the first column of the row we want to be visible, by calculating the first visible column on the left before applying the scroll and then scrolling to it.
A final note: Columns absolute left is tested against "51". This is a value I found "experimentally" by looking the JS values in the browser's developer tool, I think it depends on the table's style, you may need to change/calculate it.
Below the code:
public void scrollIntoView(T next) {
int index = datagrid.getVisibleItems().indexOf(next);
NodeList<TableCellElement> cells = datagrid.getRowElement(index).getCells();
int firstVisibleIndex = -1;
for(int i=0; i<cells.getLength() && firstVisibleIndex<0;i++)
if(UIObject.isVisible(cells.getItem(i)) && (cells.getItem(i).getAbsoluteLeft() > 51) && (cells.getItem(i).getAbsoluteTop() > 0))
firstVisibleIndex = i;
cells.getItem(firstVisibleIndex>=0? firstVisibleIndex : 0).scrollIntoView();
}
I created a widget that is a subclass of Composite and has a com.extjs.gxt.ui.client.widget.Viewport in it. Into this viewport I added my header component, a LayoutComponent (initially empty) and my footer component. I initialized the composite widget by calling initWidget at the end of the constructor that sets everything up ... something like this (some code removed for readability):
public class MyComposite extends Composite {
...
public MyComposite(...) {
viewport = new Viewport();
viewport.add(new Header());
content = new LayoutContainer();
viewport.add(content);
viewport.add(new Footer());
initWidget(viewport);
}
public void show(Widget... widgets) {
content.removeAll();
for (Widget widget: widgets) content.add(widget);
}
}
Then I add an instance of this to the RootPanel:
MyComposite myComposite = new MyComposite(...);
RootPanel.get("myComposite").add(myComposite);
And guess what... that works! I see it. The header shows, the footer shows, and the content is blank at this point. Good. Then I make the call to show and add stuff to it. Not exactly as follows but for example:
myComposite.show(new Label(...));
But nothing happens. The code does run, the add(...) method gets called from the show(...) method, there are no exceptions, but nothing (new) shows up. I don't use a Label, but that is not the problem (verified, that works elsewhere). When I inspect the DOM in the browser, I see that there is a div for the content, like there was initially, but it remained empty (i.e. no body content).
What am I missing?
Thanks!
First off, are you extending GWT Composite or GXT Composite? If it is the GXT type you will need to call initComponent() on the viewport (rather than initWidget) as described here: http://dev.sencha.com/deploy/gxtdocs/com/extjs/gxt/ui/client/widget/Composite.html
Also, try adding the following line to the end of your show method:
content.layout(true);
This will force GXT to layour the contents of your LayoutContainer, and you should at least see the new elements added to the DOM. If they still don't appear on the screen you need to change your Layout of your LayoutContainer.
I am using the ScrolledComposite for a existing control(with many children) based on the method2 mentioned here :http://www.placelab.org/toolkit/doc/javadoc/org/placelab/util/swt/SwtScrolledComposite.html
The only change is instead of creating a new shell & display I am using the existing control's parent.
I am seeing the scroll bars as expected but the existing control/content is displayed form the centre & not from the start. The first half(vertically split) of the layout is empty & the actual control/content gets displayed in the right-half.
I checked bounds, Origin, size etc. they seem to be fine.
screenshot putup here :http://img818.imageshack.us/i/contentstartsfrommiddle.jpg
Any clues
Thanks in advance
Did you delete the Composite c1? maybe that is in the left side.
You could also provide what is exactly your change to the code.