Release 1.1.0 TabPanel bug?

56 views
Skip to first unread message

Ben Alex

unread,
Aug 11, 2006, 9:11:45 PM8/11/06
to Google-We...@googlegroups.com
Hi everyone

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

j...@google.com

unread,
Aug 11, 2006, 10:03:13 PM8/11/06
to Google Web Toolkit
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.

Sashi

unread,
Aug 15, 2006, 12:26:23 PM8/15/06
to Google Web Toolkit
When is a fix expected for this? Tried to find a workaround but I dont
think there is a workaround since "children" is not accessible at all
outside the class.

Sam

unread,
Aug 15, 2006, 1:32:29 PM8/15/06
to Google Web Toolkit
Hello,
It would also be nice to access the VerticalPanel that is the top level
parent of the TabBar and the DeckPanel. This needed to be able to set
the setCellWidth and setCellHeight, for example, on the DeckPanel for
certain layout controls, especially when trying to get the TabPanel to
fit 100% vertically. The stylesheets provided don't give you access to
control the VerticalPanel's styles.

-Sam

Konstantin Scheglov

unread,
Aug 15, 2006, 1:39:15 PM8/15/06
to Google Web Toolkit
I think that TabPanel should be fully filled be widgets placed on it.
At least this is how such type of control works in all GUI toolkits.

Ian Bambury

unread,
Aug 15, 2006, 1:46:04 PM8/15/06
to Google-We...@googlegroups.com
I mentioned this yesterday re a problem trying to get widgets t position directly underneath the tabs.
 
The HTML for the tab panel is
 
<TABLE class=gwt-TabPanel cellSpacing=0 cellPadding=0><TBODY>
<TR>
<TD style="VERTICAL-ALIGN: top" align=left>

--Tab Stuff Here--

</TD></TR>
<TR>
<TD style="VERTICAL-ALIGN: top" align=left>
<DIV class=gwt-TabPanelBottom>

--Deck Stuff Here--

</DIV></TD></TR></TBODY></TABLE>
 
 
and a workaround to access the first TD is
 
 
       private TabPanel tp = new TabPanel();
       Element el = tp.getElement();
       el = DOM.getChild(el,0);
       el = DOM.getChild(el,0);
       el = DOM.getChild(el,0);
       DOM.setStyleAttribute (el,"height","1px");
 
pretty as a road crash, but it works
 
Ian
 

Konstantin Scheglov

unread,
Aug 15, 2006, 1:49:33 PM8/15/06
to Google Web Toolkit
I really don't understand when people "solve" problems in open source
libraries by using some hacks instead of:

1. lobby correct behaviour

2. change library itself to fix problem

Ian Bambury

unread,
Aug 15, 2006, 1:57:56 PM8/15/06
to Google-We...@googlegroups.com
'workaround' doesn't mean the same as 'solve'
 
1.a I don't have the time
1.b The gwt team are aware of this problem
 
2.a I don't have the time
2.b It stays working whether it is fixed or not
2.c Not everyone can fix the problem in the library whereas most can copy the workaround
 
Ian

 

Konstantin Scheglov

unread,
Aug 15, 2006, 2:04:15 PM8/15/06
to Google Web Toolkit
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.

Ian Bambury

unread,
Aug 15, 2006, 3:05:53 PM8/15/06
to Google-We...@googlegroups.com
So if you think changing gwt is the way to go and you know how to do it, why didn't you post it?
 
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.
 
"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!
 
On 15/08/06, Konstantin Scheglov <Konstanti...@gmail.com> wrote:

Konstantin Scheglov

unread,
Aug 15, 2006, 3:15:27 PM8/15/06
to Google Web Toolkit

Ian Bambury писал(а):

> 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>&nbsp;</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>&nbsp;</div>
> <div>&quot;Without workaround your program does not work. With it - you have &quot;black boxes&quot; in your software. Second one looks more dangerous.&quot;</div>
> <div>&nbsp;</div>
> <div>Damn! That's where I've been going wrong.&nbsp;I should have been&nbsp;ensuring that none of my software works.&nbsp;I feel such a fool!<br>&nbsp;</div>
> <div><span class="gmail_quote">On 15/08/06, <b class="gmail_sendername">Konstantin Scheglov</b> &lt;<a href="mailto:Konstanti...@gmail.com">Konstanti...@gmail.com</a>&gt; 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 &quot;black boxes&quot;
> <br>in your software. Second one looks more dangerous.<br><br><br><br><br></blockquote></div><br>
>
> ------=_Part_20974_8496991.1155668753073--

Ian Bambury

unread,
Aug 15, 2006, 4:01:44 PM8/15/06
to Google-We...@googlegroups.com
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).
 
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.

Konstantin Scheglov

unread,
Aug 15, 2006, 4:10:56 PM8/15/06
to Google Web Toolkit

Ian Bambury писал(а):

> 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.

Scott Blum

unread,
Aug 15, 2006, 7:30:46 PM8/15/06
to Google Web Toolkit
Ian,

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

Sashi

unread,
Aug 22, 2006, 2:32:21 PM8/22/06
to Google Web Toolkit

Nice...

Reply all
Reply to author
Forward
0 new messages