gwt dialogbox won't move - gwt

i created a dialog box using uiBinder in gwt app, it works fine except it cannot move around. i don't know what's wrong with it, do i have to set caption in order to move it around?
here is my code:
myDialog.ui.xml
<g:HTMLPanel ui:field="_glossaryPanel">
<div class="dialogBox">
<h3>content goes here..</h3>
<p>More content...</p>
</div>
</g:HTMLPanel>
myDialog.java
public class MyDialog extends DialogBox {
private static MyDialogUiBinder uiBinder = GWT.create(MyDialogUiBinder.class);
interface MyDialogUiBinder extends UiBinder<Widget, MyDialog> {
}
public MyDialog() {
setWidget(uiBinder.createAndBindUi(this));
this.setModal(true);
this.setAutoHideEnabled(true);
}
FooterView.java
public class FooterView extends Composite implements FooterPresenter.Display {
interface Binder extends UiBinder<Widget, FooterView> {
}
private static final Binder BINDER = GWT.create(Binder.class);
#UiField
Anchor _glossary;
#UiHandler("_glossary")
public void handleGlossaryClick(ClickEvent event) {
MyDialog mDialog = new MyDialog();
mDialog.setGlassEnabled(true);
mDialog.setAnimationEnabled(true);
mDialog.center();
mDialog.show();
}

See http://gwt.google.com/samples/Showcase/Showcase.html#!CwDialogBox You have to use a DialogBox (not a PopupPanel) to move the thing around.
EDIT:
I tried your code and it worked for me. Have you tried clicking in the border (not content!) to drag the dialog box around?

GWT Dialogs can't be moved around like a desktop window. There was a projected called gwt-windows that would let you do that, but it hasn't been updated in years.

Maybe you could try in your ui.xml file to change the root element type
from HTMLpanel to a FlowPanel
I saw somewhere that was saying something like this. where ? I can't remember :-(
your <div clas="dialogBox"> is, in my opinion, a bit confusing, maybe yould consider renaming to something more personal and less in gwt keywords' like.

Here is the Solution,
VerticalPanel panel;
DialogBox dialogbox;
PopupPanel glass;
VerticalPanel DialogBoxContents;
ClickListener listener;
HTML message;
Button button;
SimplePanel holder;
public void demo()
{
// Create a panel and add it to the screen
panel = new VerticalPanel();
RootPanel.get("demo").add(panel);
panel.setStyleName("table-center");
//
// Create a DialogBox with a button to close it
dialogbox = new DialogBox(false);
dialogbox.setStyleName("demo-DialogBox");
DialogBoxContents = new VerticalPanel();
dialogbox.setText("DialogBox");
message = new HTML("Click 'Close' to close");
message.setStyleName("demo-DialogBox-message");
listener = new ClickListener()
{
public void onClick(Widget sender)
{
dialogbox.hide();
}
};
button = new Button("Close", listener);
holder = new SimplePanel();
holder.add(button);
holder.setStyleName("demo-DialogBox-footer");
DialogBoxContents.add(message);
DialogBoxContents.add(holder);
dialogbox.setWidget(DialogBoxContents);
//
// Add a button to the demo to show the above DialogBox
listener = new ClickListener()
{
public void onClick(Widget sender)
{
dialogbox.center();
}
};
button = new Button("Show DialogBox", listener);
panel.add(button);
}
Check out the DEMO AT http://examples.roughian.com/index.htm#Widgets~DialogBox

"do i have to set caption in order to move it around?"
Yes.
dialogbox.setText("DialogBox");
You may drag only catpion div;
When you drag caption div, whole dialog box will move.

Related

GWT DataGrid not visible (UIBinder and LazyPanel)

I am building a GWT application.
In this application I have a number of DataGrid implementations showing data retrieved from the server. In one panel I have a TabLayoutPanel, with a DataGrid on each tab.
I am attempting to lazy-load the DataGrids when the parent tab becomes visible.
Here is the ui.xml:
<g:TabLayoutPanel width="800px" height="450px" barUnit='EM' barHeight='3'>
<g:tab>
<g:header size='7'><b>Volunteer Assignments</b></g:header>
<grid:VolunteerAssignmentGrid/>
</g:tab>
<g:tab>
<g:header size='7'><b>Volunteer Details</b></g:header>
<g:LazyPanel ui:field="lazyDetails">
<grid:VolunteerFieldsGrid/>
</g:LazyPanel>
</g:tab>
</g:TabLayoutPanel>
In the above code, VolunteerAssignmentGrid and VolunteerFieldsGrid are sub-classes of DataGrid.
The VolunteerAssignmentGrid is visible immediately and the data displays OK.
However, the VolunteerFieldsGrid on the next tab does not display at all.
The strange thing is, it is requesting the data at the correct time (when I click on the other tab), and the server response is correct. It's as if the table is not visible.
Any ideas why the second DataGrid is not visible?
EDIT:
The UiBinder class:
public class VolunteerDetailsPanel extends DialogBox {
interface Binder extends UiBinder<Widget, VolunteerDetailsPanel> {}
private static final Binder binder = GWT.create(Binder.class);
#UiField LazyPanel lazyDetails;
private Record volunteerRecord;
private String fullName;
private String volunteerId;
public VolunteerDetailsPanel(Record record) {
this.volunteerRecord = record;
fullName = volunteerRecord.getValue("forename")+" "+volunteerRecord.getValue("surname");
volunteerId = volunteerRecord.getValue("id");
setText(fullName);
}
public void initComponent() {
setWidget(binder.createAndBindUi(this));
}
#UiFactory VolunteerAssignmentGrid createAssignmentGrid() {
return new VolunteerAssignmentGrid(volunteerId, fullName);
}
#UiFactory VolunteerFieldsGrid createFieldsGrid() {
return new VolunteerFieldsGrid(volunteerId);
}
}
As requested, also the VolunteerFieldsGrid class. It extends ListGrid (one of mine, but too long to post here, all my other Grids extend it and are OK), which in turn extends GWT's DataGrid:
public class VolunteerFieldsGrid extends ListGrid {
public VolunteerFieldsGrid(String volunteerId) {
super(100, "name", false);
setWidth("100%");
ListGridColumn<?>[] columns = new ListGridColumn<?>[] {
new FieldNameColumn("Field", "name").width(75),
new TextColumn("Value", "value").width(300)
};
setColumns(columns);
ListGridDataProvider data = ListGridDataProvider.getInstance("field",
"/volunteer/"+volunteerId, "name", false);
setDataProvider(data);
}
}
You have to register a handler for SelectionEvent in the TabLayoutPanel that will call LazyPanel.setVisible(true). Try something like this in UiBinder:
#UiHandler("yourTabPanelUiField")
void onSelectionEvent(SelectionEvent event) {
//for extra functionality check if EventTarget equals the correct tab
lazyDetails.setVisible(true);
}

Height of the middle element in a GWT HeaderPanel

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.

GWT Tab panel close

I am building an application in GWT. I have a decorated tabpanel in
my application.Where in am adding panels to it dynamically.Now i want
to achieve the closing of these tabs. I want to add a close image to
the tab bar and event to that image for closing. I am using UIbinder.
the working code is like that;
private Widget getTabTitle(final Widget widget, final String title) {
final HorizontalPanel hPanel = new HorizontalPanel();
final Label label = new Label(title);
DOM.setStyleAttribute(label.getElement(), "whiteSpace", "nowrap");
ImageAnchor closeBtn = new ImageAnchor();
closeBtn.setResource(images.cross());
closeBtn.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
int widgetIndex = tabs.getWidgetIndex(widget);
if (widgetIndex == tabs.getSelectedIndex()) {
tabs.selectTab(widgetIndex - 1);
}
tabs.remove(widgetIndex);
}
});
hPanel.add(label);
hPanel.add(new HTML("&nbsp&nbsp&nbsp"));
hPanel.add(closeBtn);
hPanel.setStyleName("gwt-TabLayoutPanelTab");
return hPanel;
}
In order to add tab,
public void addTab() {
TabWriting tw = new TabWriting(); /* TabWriting in my case, this can be any widget */
tabs.add(tw, getTabTitle(tw, "Writing"));
tabs.selectTab(tw);
}
You'll going to need, ImageAnchorClass
public class ImageAnchor extends Anchor {
public ImageAnchor() {
}
public void setResource(ImageResource imageResource) {
Image img = new Image(imageResource);
img.setStyleName("navbarimg");
DOM.insertBefore(getElement(), img.getElement(), DOM
.getFirstChild(getElement()));
}}
It isn't supported natively in GWT.
You can manually try to add it.
Read this - http://groups.google.com/group/google-web-toolkit/browse_thread/thread/006bc886c1ccf5e1?pli=1
I haven't tried it personally, but look at the solution by gregor (last one).
You kinda need to do something along the lines of this
GWT Close button in title bar of DialogBox
First you need to pass in the tab header when you create the new tab. The header you pass in should have your tab text and also an X image or text label to click on. Then add a event handler on the close object that gets the widget you are adding to the tabPanel and removes it. Here is some inline code that works
public void loadTab(final Widget widget, String headingText, String tooltip) {
HorizontalPanel panel = new HorizontalPanel();
panel.setStyleName("tabHeader");
panel.setTitle(tooltip);
Label text = new Label();
text.setText(headingText);
text.setStyleDependentName("text", true);
Label close = new Label();
close.setText("X");
close.setTitle(closeText_ + headingText);
text.setStyleDependentName("close", true);
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert("close this tab");
ClientGlobal.LOG.info("widget : " + tabPanel_.getWidgetIndex(widget));
tabPanel_.remove(tabPanel_.getWidgetIndex(widget));
}
});
panel.add(text);
panel.add(close);
panel.setCellHorizontalAlignment(text, HasHorizontalAlignment.ALIGN_LEFT);
panel.setCellHorizontalAlignment(close, HasHorizontalAlignment.ALIGN_RIGHT);
tabPanel_.add(widget, panel);
tabPanel_.getTabWidget(widget).setTitle(tooltip);
tabPanel_.selectTab(widget);
}

DialogBox in GWT isn't draggable or centred

I'm new to GWT programming. So far I have a DialogBox which is supposed to collect a login and a password, which can if required launch another DialogBox that allows someone to create a new account.
The first of these two DialogBoxes always appears at the top left of the browser screen, and can't be dragged, although part of the definition of a DialogBox is that it can be dragged. However, the second DialogBox can be dragged about the screen without any problem.
What I'd really like is for the first DialogBox to appear in the middle of the screen & be draggable, both of which I thought would happen automatically, but there's not.
So, what things can stop a DialogBox from being draggable? There is nothing on the RootPanel yet. Does that make a difference?
Code fragments available if they help, but perhaps this general outline is enough for some pointers.
Thanks
Neil
Use dialogBox.center() This will center your DialogBox in the middle of the screen. Normally a DialogBox is by default draggable.
Just tried it out and it doens't matter if your RootPanel is empty our not. When I just show the DialogBox on ModuleLoad it is draggable and it is centered. Probably the problem is situated somewhere else.
This is the example of google itself:
public class DialogBoxExample implements EntryPoint, ClickListener {
private static class MyDialog extends DialogBox {
public MyDialog() {
// Set the dialog box's caption.
setText("My First Dialog");
// DialogBox is a SimplePanel, so you have to set its widget property to
// whatever you want its contents to be.
Button ok = new Button("OK");
ok.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
MyDialog.this.hide();
}
});
setWidget(ok);
}
}
public void onModuleLoad() {
Button b = new Button("Click me");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Instantiate the dialog box and show it.
new MyDialog().show();
}
}
Here more information about the DialogBox.
Without seeing any of your code it's hard to tell what's going wrong. The following code works for me (ignore the missing styling...):
public void onModuleLoad() {
FlowPanel login = new FlowPanel();
Button create = new Button("create");
login.add(new TextBox());
login.add(new TextBox());
login.add(create);
create.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final DialogBox box = new DialogBox();
FlowPanel panel = new FlowPanel();
Button close = new Button("close");
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
box.hide();
}
});
panel.add(new Label("some content"));
panel.add(close);
box.setWidget(panel);
box.center();
}
});
DialogBox firstBox = new DialogBox(false, true);
firstBox.setWidget(login);
firstBox.center();
}
Both boxes are draggable and shown in the center of your browser window.
Looks like you're overriding this method in Widget:
public void fireEvent(GwtEvent<?> event) {
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
}
In Widget, handlerManager refers to a private HandlerManager.
Either add super.fireEvent(event) to your method or as you have done rename it.
Well, with vast amounts of trial and error I have found the problem, which was just this: I had a method in an object I'd based on DialogBox called fireEvent, which looked like this:
public void fireEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
Then, when a button was clicked on the DialogBox, an event would be created and sent off to the handlerManager to be fired properly.
And it turns out that if I change it to this (LoginEvent is a custom-built event):
public void fireEvent(LoginEvent event)
{
handlerManager.fireEvent(event);
}
... or to this ....
public void fireAnEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
the DialogBox is draggable. However, if the method begins with the line
public void fireEvent(GwtEvent<?> event)
then the result is a DialogBox which can't be dragged.
I'm a bit unsettled by this, because I can't fathom a reason why my choice of name of a method should affect the draggability of a DialogBox, or why using a base class (GwtEvent) instead of a custom class that extends it should affect the draggability. And I suspect there are dozens of similar pitfalls for a naive novice like me.
(Expecting the DialogBox to centre itself was simply my mistake.)

Replace GWT DockLayoutPanel Contents

I'm trying to replace the contents of the CENTER portion of a DockLayoutPanel from a MenuBar. The MenuBar will sit at the North, but "content" (forms, reports, etc) will reside in Center.
I thought I could do it by grabbing the entire DockLayoutPanel from the RootPanel (index 0, since that's the only widget directly attached to it), then somehow remove the current contents of center and insert the new. Unfortunately, getWidget(int index) is non-static, so it's not working.
Can anyone how me with the right way to do this? Non-working code is below:
// snipped package and import details
public class menubar extends Composite {
private static menubarUiBinder uiBinder = GWT.create(menubarUiBinder.class);
interface menubarUiBinder extends UiBinder<Widget, menubar> {
}
#UiField MenuBar applicationMenuBar;
#UiField MenuBar processMenuBar;
#UiField MenuBar reportsMenuBar;
#UiField MenuItem addPowerRequirementCmd;
#UiField MenuItem powerUsageReportCmd;
public menubar() {
initWidget(uiBinder.createAndBindUi(this));
// command to replace whatever is in DockLayoutPanel.CENTER w/ AddPowerRequirement
// FormPanel
addPowerRequirementCmd.setCommand(new Command() {
#Override
public void execute() {
// get DockLayoutPanel from the RootPanel (it's the only widget, should be
// index 0
DockLayoutPanel dlp = (DockLayoutPanel) RootPanel.getWidget(0);
// clear out DockLayoutPanel.CENTER
// insert the FormLayoutPanel into DockLayoutPanel.CENTER
dlp.add(new PowerRequirementForm());
}
});
// command to replace whatever is in DockLayoutPanel.CENTER w/ power usage report
powerUsageReportCmd.setCommand(new Command() {
#Override
public void execute() {
}
});
}
}
Thanks!
Use a ui:field attribute, like you do for the MenuBar, to get a reference to the DockLayoutPanel from UiBinder:
<g:DockLayoutPanel ui:field="dockPanel"/>
and in the class:
#UiField DockLayoutPanel dockPanel;
However, it sounds like you want to have a set of widgets that are shown in the center of the panel depending on application state. A DeckPanel is a better solution for this:
<g:DockLayoutPanel>
<g:center>
<g:DeckPanel ui:field="deck">
<g:FlowPanel>Panel #0</g:FlowPanel>
<g:FlowPanel>Panel #1</g:FlowPanel>
</g:DeckPanel>
</g:center>
</g:DockLayoutPanel>
And then to switch the displayed child of the DeckPanel:
deck.showWidget(1); // Show Panel #1
deck.showWidget(0); // Show panel #0