still new to java & gwt but am making baby-steps thanks to you all.
I'm not sure where this problem is, might be CSS, might be my light-
weight understanding of java and / or GWT. I am building an app that
will have an initial login screen then a fairly static UI after login.
The first time to the page there is no session cookie so I create a
VerticalPanel with three sections: header, footer and what will be the
body.
Once I have logged in I want to change the "body" section to the real
UI. This is sort of working now but the rendered result is not right.
So I start by rendering a FlexTable to hold the login "form". This
form has a submit button and that has an on-click event. The onclick
code looks like:
final Button submit = new Button("Login");
submit.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
RequestBuilder login = new
RequestBuilder(RequestBuilder.POST, loginURL);
login.setHeader("Content-Type", "application/x-www-form-
urlencoded");
try {
StringBuffer postData = new StringBuffer();
// ... build postData ...
Request response =
login.sendRequest(postData.toString(),
new RequestCallback() {
public void onError(Request request,
Throwable exception) {
Window.alert("Auth failed");
}
public void onResponseReceived(
Request request,
Response response) {
//
// Auth succeeds. slip in the UI in
// place of the login form.
//
Widget tmp = drawMainUI();
MainPanel.remove(1);
MainPanel.insert(tmp, 1);
//response.getHeadersAsString()
}
}
);
}
catch (RequestException e) {
Window.alert("Failed to send the request: " +
e.getMessage());
}
}
});
loginFormTable.setWidget(2, 0, submit);
loginFormTable.getFlexCellFormatter().setColSpan(2, 0, 2);
This is working. onResponseReceived is called on success and the form
is swapped for the regular UI. THe problem is that the regular UI has
lost its formatting.
The regular UI should be a DockPanel with a WEST panel that should be
20% wide and 40em high. It has been this in prior tests before I
tried to do the magic panel shuffle. Now though the WEST panel is
just wide enough to hold the word "West".
the code to produce the main UI is:
public Widget drawMainUI() {
DockPanel panel = new DockPanel();
TabPanel tabPanel = new TabPanel();
HTML westHTML = new HTML(
"<div style=\"background-color:#eee;\">"
+
"<p>Left</p></div>");
HTML centerHTML = new HTML(
"<div style=\"background-color:#aaa;" +
" width:100%;\">" +
"<p>Center</p></div>");
tabPanel.add(new HTML("test1"), "test1");
tabPanel.add(new HTML("test2"), "test2");
tabPanel.add(new HTML("test3"), "test3");
tabPanel.add(new HTML("test4"), "test4");
panel.add(westHTML, DockPanel.WEST);
panel.add(tabPanel, DockPanel.CENTER);
panel.setCellWidth(westHTML, "20%");
panel.setCellHeight(westHTML, "20em");
return(panel);
}
I am sort of making a general "help" plea but a more specific
questions might be:
Is this onClick approach "the best" way to do this content switch?
Am I actually doing it the correct way?
Inside your drawMainUI function, I'm assuming those HTML panels are
there for testing and you'll put something else in there later. If you
are opposed to having style sheets, you could create an AbsolutePanel
(or any panel really) and run the folowoing
AbsolutePanel panel = new AbsolutePanel();
DOM.setStyleAttribute(panel.getElement, "background-color", "#aaa")
for example. Then you are free to use any of the panels and not just
the HTML ones so you can enter in your CSS.
I'm also assuming the drawUIPanel is meant to be the 2nd widget in
your panel and not the first.
Your code will be more effiencent if you create your own seperate
widget and then expose various methods to the world where you can set
the code in the different panels.
An example of what this might look like with your current code
public class MyCustomWidget extends Composite{
DockPanel panel;
TabPanel tabPanel;
public MyCustomWIdget(){
panel = new DockPanel();
tabPanel = new TabPanel();
HTML westHTML = new HTML(
"<div style=\"background-color:#eee;\">"
+
"<p>Left</p></div>");
HTML centerHTML = new HTML(
"<div style=\"background-color:#aaa;" +
" width:100%;\">" +
"<p>Center</p></div>");
tabPanel.add(new HTML("test1"), "test1");
tabPanel.add(new HTML("test2"), "test2");
tabPanel.add(new HTML("test3"), "test3");
tabPanel.add(new HTML("test4"), "test4");
panel.add(westHTML, DockPanel.WEST);
panel.add(tabPanel, DockPanel.CENTER);
panel.setCellWidth(westHTML, "20%");
panel.setCellHeight(westHTML, "20em");
}
public DockPanel getDockPanel(){
return panel;
}
public TabPanel getTabPanel(){
return tabPanel;
}
Now you have access to the DockPanel and the tabPanel after the object
is created and you can add/replace various objects inside there and
not have to worry about recreating your styles. This should also be
faster as you will not have to create a new DockPanel and TabPanel
everytime you switch. You will just have to change teh elements inside
of those panels.
Much of the preformance stuff is based on guesses and my own personal
experience. Your mileage may vary.
-Jeff
On "Composite"s, are there ever aggregations of widgets that are not
suited for Composite-ing? I'm beting no but you bring up "Best
Practices". Let's say that I am creating a large form and all fields
will have labels. Is it best to Composite the label and the form
element as a unit and then possible Composite the Composite-ed label/
field units into the form? Is it better to just build the form and
Composite the whole thing instead?
I can't think of any reason to not make a complex set of UI functions
into a a composite. It allows for easier reuse later on, and in
general easier to follow code. As far as creating your own label/input
box composite, that can work, or there might be a reason not to do
that, for instance having a header row and an input row(s).
-Jeff