Congratulations and thanks to the GWT team for the 1.1.0 release.
I've tracked down a TabPanel problem when using the insert method which
accepts the boolean asHTML argument. The 1.1.0 TabPanel overloaded
insert methods look like this:
public void insert(Widget widget, String tabText, int beforeIndex) {
children.insert(widget, beforeIndex);
tabBar.insertTab(tabText, beforeIndex);
deck.insert(widget, beforeIndex);
}
public void insert(Widget widget, String tabText, boolean asHTML,
int beforeIndex) {
// *** BUG?: missing children.insert(widget, beforeIndex)
tabBar.insertTab(tabText, asHTML, beforeIndex);
deck.insert(widget, beforeIndex);
}
It looks like a bug to me, but could the GWT team please confirm and I
will go log a bug.
Thanks
Ben
Thanks for catching this. Looks like I missed a spot in the unit
tests! I've noted it for the issues list, and will fix it as soon as
possible.
Thanks,
joel.
-Sam
1. lobby correct behaviour
2. change library itself to fix problem
b. I'm not sure that it will work after fix.
c. It is always dangerous to use such workarounds if you don't
understand how they work. In any case you will be in trouble. Without
workaround your program does not work. With it - you have "black boxes"
in your software. Second one looks more dangerous.
> So if you think changing gwt is the way to go and you know how to do it, why
> didn't you post it?
See at the end of message.
>
> I don't know anything about gwt, I've only been looking at it for 3 days.
> I've never used Java before. I have no idea how to change gwt, or where, or
> how to ensure all my changes remain in place when updates are released. HTML
> I can cope with.
Ok, now I understand. Sorry, I just thought that all people here know
and use Java.
> "Without workaround your program does not work. With it - you have "black
> boxes" in your software. Second one looks more dangerous."
>
> Damn! That's where I've been going wrong. I should have been ensuring that
> none of my software works. I feel such a fool!
No. You should ensure that your software works. But also should known
HOW it works. Without this you will have unstable, unmaintable code.
What if workaround has bug? How will you fix it? What if it has some
side effect that you don't know and that will hurt you when you do
something in different place of your software?
Here is code for TabPanel that I use:
/*
* Copyright 2006 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
may not
* use this file except in compliance with the License. You may obtain
a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See
the
* License for the specific language governing permissions and
limitations under
* the License.
*/
package com.google.gwt.user.client.ui;
import java.util.Iterator;
/**
* A panel that represents a tabbed set of pages, each of which
contains another
* widget. Its child widgets are shown as the user selects the various
tabs
* associated with them. The tabs can contain arbitrary HTML.
*
* <p>
* <img class='gallery' src='TabPanel.png'/>
* </p>
*
* <p>
* Note that this widget is not a panel per se, but rather a
* {@link com.google.gwt.user.client.ui.Composite} that aggregates a
* {@link com.google.gwt.user.client.ui.TabBar} and a
* {@link com.google.gwt.user.client.ui.DeckPanel}. It does, however,
implement
* {@link com.google.gwt.user.client.ui.HasWidgets}.
* </p>
*
* <h3>CSS Style Rules</h3>
* <ul class='css'>
* <li>.gwt-TabPanel { the tab panel itself }</li>
* <li>.gwt-TabPanelBottom { the bottom section of the tab panel (the
deck
* containing the widget) }</li>
* </ul>
*
* <p>
* <h3>Example</h3> {@example com.google.gwt.examples.TabPanelExample}
* </p>
*/
public class TabPanel extends Composite implements TabListener,
SourcesTabEvents, HasWidgets, IndexedPanel {
private WidgetCollection children = new WidgetCollection(this);
private DeckPanel deck = new DeckPanel();
private TabBar tabBar = new TabBar();
private TabListenerCollection tabListeners;
/**
* Creates an empty tab panel.
*/
public TabPanel() {
VerticalPanel panel = new VerticalPanel();
panel.add(tabBar);
panel.add(deck);
tabBar.setWidth("100%");
panel.setCellHeight(deck, "100%");
deck.setHeight("100%");
tabBar.addTabListener(this);
initWidget(panel);
setStyleName("gwt-TabPanel");
deck.setStyleName("gwt-TabPanelBottom");
}
public void add(Widget w) {
throw new UnsupportedOperationException(
"A tabText parameter must be specified with add().");
}
/**
* Adds a widget to the tab panel.
*
* @param w the widget to be added
* @param tabText the text to be shown on its tab
*/
public void add(Widget w, String tabText) {
insert(w, tabText, getWidgetCount());
}
/**
* Adds a widget to the tab panel.
*
* @param w the widget to be added
* @param tabText the text to be shown on its tab
* @param asHTML <code>true</code> to treat the specified text as
HTML
*/
public void add(Widget w, String tabText, boolean asHTML) {
insert(w, tabText, asHTML, getWidgetCount());
}
public void addTabListener(TabListener listener) {
if (tabListeners == null)
tabListeners = new TabListenerCollection();
tabListeners.add(listener);
}
public void clear() {
while (getWidgetCount() > 0)
remove(getWidget(0));
}
/**
* Gets the deck panel within this tab panel.
*
* @return the deck panel
*/
public DeckPanel getDeckPanel() {
return deck;
}
/**
* Gets the tab bar within this tab panel
*
* @return the tab bar
*/
public TabBar getTabBar() {
return tabBar;
}
public Widget getWidget(int index) {
return children.get(index);
}
public int getWidgetCount() {
return children.size();
}
public int getWidgetIndex(Widget widget) {
return children.indexOf(widget);
}
/**
* Inserts a widget into the tab panel.
*
* @param widget the widget to be inserted
* @param tabText the text to be shown on its tab
* @param asHTML <code>true</code> to treat the specified text as
HTML
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget widget, String tabText, boolean asHTML,
int beforeIndex) {
children.insert(widget, beforeIndex);
tabBar.insertTab(tabText, asHTML, beforeIndex);
deck.insert(widget, beforeIndex);
}
/**
* Inserts a widget into the tab panel.
*
* @param widget the widget to be inserted
* @param tabText the text to be shown on its tab
* @param beforeIndex the index before which it will be inserted
*/
public void insert(Widget widget, String tabText, int beforeIndex) {
children.insert(widget, beforeIndex);
tabBar.insertTab(tabText, beforeIndex);
deck.insert(widget, beforeIndex);
}
public Iterator iterator() {
return children.iterator();
}
public boolean onBeforeTabSelected(SourcesTabEvents sender, int
tabIndex) {
if (tabListeners != null)
return tabListeners.fireBeforeTabSelected(this, tabIndex);
return true;
}
public void onTabSelected(SourcesTabEvents sender, int tabIndex) {
deck.showWidget(tabIndex);
if (tabListeners != null)
tabListeners.fireTabSelected(this, tabIndex);
}
public boolean remove(int index) {
return remove(getWidget(index));
}
/**
* Removes the given widget, and its associated tab.
*
* @param widget the widget to be removed
*/
public boolean remove(Widget widget) {
int index = getWidgetIndex(widget);
if (index == -1)
return false;
children.remove(widget);
tabBar.removeTab(index);
deck.remove(widget);
return true;
}
public void removeTabListener(TabListener listener) {
if (tabListeners != null)
tabListeners.remove(listener);
}
/**
* Programmatically selects the specified tab.
*
* @param index the index of the tab to be selected
*/
public void selectTab(int index) {
tabBar.selectTab(index);
}
}
>
> On 15/08/06, Konstantin Scheglov <Konstanti...@gmail.com> wrote:
> >
> >
> > a. You don't have time to change couple lines of code in GWT, but you
> > have time to look in dirty HTML/DOM tricks. Hm...
> >
> > b. I'm not sure that it will work after fix.
> >
> > c. It is always dangerous to use such workarounds if you don't
> > understand how they work. In any case you will be in trouble. Without
> > workaround your program does not work. With it - you have "black boxes"
> > in your software. Second one looks more dangerous.
> >
> >
> > >
> >
>
> ------=_Part_20974_8496991.1155668753073
> Content-Type: text/html; charset=ISO-8859-1
>
> <div>So if you think changing gwt is the way to go and you know how to do it, why didn't you post it?</div>
> <div> </div>
> <div>I don't know anything about gwt, I've only been looking at it for 3 days. I've never used Java before. I have no idea how to change gwt, or where, or how to ensure all my changes remain in place when updates are released. HTML I can cope with.
> <br> </div>
> <div>"Without workaround your program does not work. With it - you have "black boxes" in your software. Second one looks more dangerous."</div>
> <div> </div>
> <div>Damn! That's where I've been going wrong. I should have been ensuring that none of my software works. I feel such a fool!<br> </div>
> <div><span class="gmail_quote">On 15/08/06, <b class="gmail_sendername">Konstantin Scheglov</b> <<a href="mailto:Konstanti...@gmail.com">Konstanti...@gmail.com</a>> wrote:</span>
> <blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid"><br>a. You don't have time to change couple lines of code in GWT, but you<br>have time to look in dirty HTML/DOM tricks. Hm...
> <br><br>b. I'm not sure that it will work after fix.<br><br>c. It is always dangerous to use such workarounds if you don't<br>understand how they work. In any case you will be in trouble. Without<br>workaround your program does not work. With it - you have "black boxes"
> <br>in your software. Second one looks more dangerous.<br><br><br><br><br></blockquote></div><br>
>
> ------=_Part_20974_8496991.1155668753073--
> Thanks for the code. Hardly the "couple of lines" you mentioned though, but
> maybe you only changed a couple of lines of it. Also, I have no idea what to
> do with it (any suggestions should be anatomically feasable).
You can extract gwt-user.jar (it has both source and class files),
setup your IDE to use it as project. Then you can change it, build new
jar, etc. Now easy task for beginner. :-(
> I don't understand your problem with someone providing a workaround. Do
> *you*, for example, put workarounds in css to deal with the vagaries of the
> different browsers, or do you write standards-compliant css and lobby
> Microsoft et al to fix the broken box and all the rest of it.
>
> The people I work for prefer 'it does what you asked for' to 'it doesn't
> work, lobby Microsoft about it'. They tend not to pay for stuff that doesn't
> work.
Of course, when you don't have choice, you have to use workarounds.
But as developer your should understand, that this is bad and try to
find better way. For GWT (and many other open source projects) we have
it.
If you're using a good IDE (such as Eclipse), I've found the easiest
thing to do as of 1.1.0 is to open the (non-editable) framework version
of the class in my IDE. Then I create the exact same class in my own
project and copy-paste in the code from the framework version. As long
as your own project's source folder is higher on the classpath than
gwt-user.jar, your class will "win".
I like this approach for a couple of reasons. First, it's
self-documenting: my project simply contains some files that live in
the com.google.gwt.user.client package, so it's obvious where I've made
changes. Secondly, it makes upgrading very easy. When it's time to
upgrade, I can review the changes I made to my versions of the classes
and compare them to the new versions, and decide what to do from there.
Scott
Nice...