I've a TabPanel which contains a SplitLayoutPanel with inside two ScrollPanel, one in the Center and one in the South edge of the dock. When I resize the browser window my SplitLayoutPanel doesn't resize automatically. I try to solve the problem with this code:
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
setSplitPanelSize();
}
});
protected void setSplitPanelSize() {
if (getParent() != null) {
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
#Override
public void execute() {
mainSplitPanel.setSize(getParent().getOffsetWidth() + "px", getParent().getOffsetHeight() + "px");
}
});
}
}
but using getParent() in order to retrieve TabPanel size is an unsafe soultion. Is there another way to resize SplitLayoutPanel (and its elements) on browser resizing?
Zasz is correct.
SplitLayoutPanel mainPanel = new SplitLayoutPanel() {
#Override
public void onResize() {
super.onResize();
//some other resizing stuff
}
};
SplitLayoutPanel implements RequiresResize and ProvidesResize as it extends from DockLayoutPanel. You can override the onResize() method to do what you wish. Also it may be necessary to call the base onResize() method as well in your override.
Related
I have a vaadin 7 client widget which has a DIV element in it. I am trying to register the click event on DIV elment through Event.sinkEvents. however the browser events never get fired. Here is the piece of code
public class MyWidget extends Widget{
private final DivElement popup = Document.get().createDivElement();
public MyWidget() {
initDOM();
initListeners();
}
private void initDOM(){
popup.setClassName(STYLECLASS);
setElement(popup);
}
public void initListeners(){
Event.sinkEvents(popup, Event.ONCLICK|Event.MOUSEEVENTS);
Event.setEventListener(popup, new EventListener() {
#Override
public void onBrowserEvent(Event event) {
Window.alert("clicked"); // this never get fired.
event.stopPropagation();
}
});
}
Please suggest any pointer.
Regards,
Azhar
There is never a need to do DOM.setEventListener in a widget (and in fact it should be avoided) - just override the widget's own onBrowserEvent method after sinking those events. By sinking those events and attaching the widget to a parent, GWT has internally called setEventListener on the widget itself so that it can handle its own events.
Instead of using Event#sinkEvents, use Widget#sinkEvents. And override the widget's onBrowseEvent to handle the events.
This should do it:
public class MyWidget extends Widget{
private final DivElement popup = Document.get().createDivElement();
public MyWidget() {
initDOM();
}
private void initDOM(){
popup.setClassName(STYLECLASS)
setElement(popup);
sinkEvents(Event.ONCLICK|Event.MOUSEEVENTS);
}
#Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
if(event.getTypeInt()==Event.ONCLICK){
Window.alert("Clicked");
}
}
}
Yes, Overridding the onBrowserEvent method works.
below code worked.
Event.sinkEvents(popup, Event.ONCLICK|Event.MOUSEEVENTS);
replaced with
sinkEvents(Event.ONCLICK|Event.MOUSEEVENTS);
Will sink the events on widget and not on any DIV. after that below brower event got fired.
public void onBrowserEvent(Event event) {
Window.alert("clicked"); // this never get fired.
event.stopPropagation();
}
});
I am using a GWT HeaderPanel. As a middle element, I am using a DockLayoutPanel as follows:
<g:DockLayoutPanel width="1200px" height="100%">
<g:west size="220">
<g:HTMLPanel styleName="{style.debug}">
something <br />
something <br />
</g:HTMLPanel>
</g:west>
</g:DockLayoutPanel>
The page renders fine but, if the browser window is shrunk vertically, the middle panel goes on top of the footer, which is of course not what you would want with a header panel.
I rather like to have the fixed footer, which is why I am not doing the whole thing using DockLayoutPanel. What am I doing wrong? Thanks!
EDIT: ok, actually, if the window is grown vertically, the middle panel still does not resize
EDIT2: The HeaderPanel is directly in the root panel and looks like this:
<g:HeaderPanel>
<my.shared:Header></my.shared:Header>
<my.shared:Middle></my.shared:Middle>
<my.shared:Footer></my.shared:Footer>
</g:HeaderPanel>
Layout panels 101: HeaderPanel is a RequiresResize panel, so it must either be put into a ProvidesResize panel, such as RootLayoutPanel, (or as the middle panel of a HeaderPanel [1]) or be given an explicit fixed size.
[1] HeaderPanel does not implement ProvidesResize because it only fulfills the contract for its middle panel.
The following approach worked for me. It's based on Zack Linder's advice
Google Web Toolkit ›layout panel problem
(1) Attach a HeaderLayoutPanel to your RootLayoutPanel. The headerLayoutPanel is a class you create that extends HeaderPanel and implements ProvidesResize().
import com.google.gwt.user.client.ui.HeaderPanel;
import com.google.gwt.user.client.ui.ProvidesResize;
import com.google.gwt.user.client.ui.SimpleLayoutPanel;
import com.google.gwt.user.client.ui.Widget;
public class HeaderLayoutPanel extends HeaderPanel implements ProvidesResize {
SimpleLayoutPanel contentPanel;
public HeaderLayoutPanel() {
super();
contentPanel=new SimpleLayoutPanel();
}
#Override
public void setContentWidget(Widget w) {
contentPanel.setSize("100%","100%");
contentPanel.setWidget(w);
super.setContentWidget(contentPanel);
}
public void onResize() {
int w=Window.getClientWidth();
int h=Window.getClientHeight();
super.setPixelSize(w, h);
}
}
(2) Next, instantiate a HeaderLayoutPanel. The header and footer widgets are assigned
a fixed height (e.g. menu bar height), and their width adjusts automatically to the
width of the panel. The center widget should be a ProvidesSize. I used a LayoutPanel.
For example,
public class AppViewer extends Composite implements MyApp.AppDisplay {
private HeaderLayoutPanel allContentsPanel;
MenuBar menuBarTop;
MenuBar menuBarBottom;
LayoutPanel dataPanel;
public AppViewer() {
allContentsPanel = new HeaderLayoutPanel();
menuBarTop = new MenuBar(false);
menuBarBottom = new MenuBar(false);
dataPanel = new LayoutPanel();
menuBarTop.setHeight("30px");
menuBarBottom.setHeight("20px");
allContentsPanel.setHeaderWidget(menuBarTop);
allContentsPanel.setFooterWidget(menuBarBottom);
allContentsPanel.setContentWidget(dataPanel);
initWidget(allContentsPanel);
}
#Override
public void doOnResize() {
allContentsPanel.onResize();
}
}
(3) The center widget (LayoutPanel) will hold the DeckLayoutPanel, which I defines in a
separate Composite (but you can do whatever you want). For example,
public class MyDataView extends Composite implements MyDataPresenter.DataDisplay {
private DockLayoutPanel pnlAllContents;
private HorizontalPanel hpnlButtons;
private HorizontalPanel hpnlToolbar;
private VerticalPanel pnlContent;
public MyView() {
pnlAllContents=new DockLayoutPanel(Unit.PX);
pnlAllContents.setSize("100%", "100%");
initWidget(pnlAllContents);
hpnlToolbar = new HorizontalPanel();
hpnlToolbar.setWidth("100%");
pnlAllContents.addNorth(hpnlToolbar, 30);
hpnlButtons = new HorizontalPanel();
hpnlButtons.setWidth("100%");
pnlAllContents.addSouth(hpnlButtons,20);
pnlContent=new VerticalPanel();
//center widget - takes up the remainder of the space
pnlAllContents.add(pnlContent);
...
}
}
(4) Finally everything gets tied together in the onModuleLoad() class: AppViewer generates
the display which is added to the RootLayoutPanel, and MyDataView generates a display.asWidget()
that is added to the container. For example,
public class MyApp implements EntryPoint,Presenter{
private HasWidgets container=RootLayoutPanel.get();
private static AppDisplay display;
private DataPresenter dataPresenter;
public interface AppDisplay extends Display{
#Override
Widget asWidget();
HasWidgets getContentContainer();
void doOnResize();
}
#Override
public void onModuleLoad() {
display=new AppViewer();
dataPresenter = new DataPresenter();
display.getContentContainer().add(dataPresenter.getDisplay().asWidget());
container.add(display.asWidget());
bind();
}
#Override
public void bind() {
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
display.doOnResize();
}
});
}
#Override
public com.midasmed.client.presenter.Display getDisplay() {
return display;
}
}
Hope this helps!
Well, I haven't been able to solve this but, for future visitors: the same can be achieved (minus the problem I couldn't fix) using a DockLayourPanel with a north, center and south components.
I'm unable to get the height of the widget in my code
docklayoutpanel.setHeight("1900px");
String height=Integer.toString(docklayoutpanel.getOffsetHeight());
String heightt=height+"px";
System.out.println(heightt);
but the o/p is always 0px.
The question is old but I had the same problem and it took me quite long to solve it. So to help others here is my solution.
I'm using UIBinder to constuct my views and in the constructor I added a Scheduler.
public class MyWidgetImpl extends Composite implements MyWidget {
#UiTemplate("MyWidget.ui.xml")
interface MainViewUiBinder extends UiBinder<Widget, MyWidgetImpl> {
}
#UiField(provided = true)
InputPanel inputPanel;
#UiField(provided = true)
ResultPanel resultPanel;
public MyWidgetImpl() {
inputPanel = ClientFactory.getInputPanel();
resultPanel = ClientFactory.getResultPanel();
MainViewUiBinder uiBinder = GWT.create(MainViewUiBinder.class);
initWidget(uiBinder.createAndBindUi(this));
Window.addResizeHandler(new ResizeHandler() {
public void onResize(ResizeEvent event) {
resize();
}
});
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
public void execute() {
resize();
}
});
}
private void resize() {
if(Window.getClientHeight() > resultPanel.getCellTree().getAbsoluteTop())
resultPanel.getScrollPanel().setHeight((Window.getClientHeight() - resultPanel.getCellTree().getAbsoluteTop()) + "px");
}
}
It depends where do you call this code. Height will be available after load i.e. you can get you height in onLoad() method
I have a custom widget that is actually an image, and i would like to be able to drag it inside an AbsolutePanel and get its coordinates every time. I would like to use the new DND API from GWT 2.4, but i'm having a hard time to implement it. Can someone propose the basic steps i must take?
The new DnD API introduced with GWT 2.4 doesn't currently support the AbsolutePanel (see the implementations of the HasAllDragAndDropHandlers interface). Looking at the implementation of FocusPanel it shouldn't be too hard to enable it for other panels.
Here's a quick proof of concept on how to solve your problem:
public void onModuleLoad() {
DragImage image = new DragImage();
image.setUrl(Resources.INSTANCE.someImage().getSafeUri());
final DropAbsolutePanel target = new DropAbsolutePanel();
target.getElement().getStyle().setBorderWidth(1.0, Unit.PX);
target.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
target.getElement().getStyle().setBorderColor("black");
target.setSize("200px", "200px");
// show drag over effect
target.addDragOverHandler(new DragOverHandler() {
#Override
public void onDragOver(DragOverEvent event) {
target.getElement().getStyle().setBackgroundColor("#ffa");
}
});
// clear drag over effect
target.addDragLeaveHandler(new DragLeaveHandler() {
#Override
public void onDragLeave(DragLeaveEvent event) {
target.getElement().getStyle().clearBackgroundColor();
}
});
// enable as drop target
target.addDropHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
event.preventDefault();
// not sure if the calculation is right, didn't test it really
int x = (event.getNativeEvent().getClientX() - target.getAbsoluteLeft()) + Window.getScrollLeft();
int y = (event.getNativeEvent().getClientY() - target.getAbsoluteTop()) + Window.getScrollTop();
target.getElement().getStyle().clearBackgroundColor();
Window.alert("x: " + x + ", y:" + y);
// add image with same URL as the dropped one to absolute panel at given coordinates
target.add(new Image(event.getData("text")), x, y);
}
});
RootPanel.get().add(image);
RootPanel.get().add(target);
}
And here the custom panel
public class DropAbsolutePanel extends AbsolutePanel implements HasDropHandlers, HasDragOverHandlers,
HasDragLeaveHandlers {
#Override
public HandlerRegistration addDropHandler(DropHandler handler) {
return addBitlessDomHandler(handler, DropEvent.getType());
}
#Override
public HandlerRegistration addDragOverHandler(DragOverHandler handler) {
return addBitlessDomHandler(handler, DragOverEvent.getType());
}
#Override
public HandlerRegistration addDragLeaveHandler(DragLeaveHandler handler) {
return addBitlessDomHandler(handler, DragLeaveEvent.getType());
}
}
and image class:
public class DragImage extends Image {
public DragImage() {
super();
initDnD();
}
private void initDnD() {
// enables dragging if browser supports html5
getElement().setDraggable(Element.DRAGGABLE_TRUE);
addDragStartHandler(new DragStartHandler() {
#Override
public void onDragStart(DragStartEvent event) {
// attach image URL to drag data
event.setData("text", getUrl());
}
});
}
}
When we double click on any view in eclipse or we resize it,how to detect the scenario in code. Currently my piece of code is extending ViewPart,now how can I detect the resizing in view.
Try this:
#Override
public void createPartControl(final Composite parent) {
parent.addControlListener(new ControlAdapter() {
#Override
public void controlResized(final ControlEvent e) {
System.out.println("RESIZE");
}
});
}