diff options
author | Jouni Koivuviita <jouni.koivuviita@itmill.com> | 2009-05-08 12:41:04 +0000 |
---|---|---|
committer | Jouni Koivuviita <jouni.koivuviita@itmill.com> | 2009-05-08 12:41:04 +0000 |
commit | fe60cb2e249b9ccba2ae19d3919a1ac1eb2eb7c3 (patch) | |
tree | da1bccb2521d111412fc99d3abbc86e07322d8fd | |
parent | bd46d5a0db8273834a4e9af2ae3b649ba1ce273f (diff) | |
download | vaadin-framework-fe60cb2e249b9ccba2ae19d3919a1ac1eb2eb7c3.tar.gz vaadin-framework-fe60cb2e249b9ccba2ae19d3919a1ac1eb2eb7c3.zip |
Merges from 6.0 branch.
svn changeset:7682/svn branch:theme_2009_03
14 files changed, 561 insertions, 132 deletions
diff --git a/src/com/itmill/toolkit/demo/sampler/features/accordions/AccordionDisabledExample.java b/src/com/itmill/toolkit/demo/sampler/features/accordions/AccordionDisabledExample.java index 705a857fd7..14d089809c 100644 --- a/src/com/itmill/toolkit/demo/sampler/features/accordions/AccordionDisabledExample.java +++ b/src/com/itmill/toolkit/demo/sampler/features/accordions/AccordionDisabledExample.java @@ -8,6 +8,7 @@ import com.itmill.toolkit.ui.Label; import com.itmill.toolkit.ui.VerticalLayout;
import com.itmill.toolkit.ui.Button.ClickEvent;
import com.itmill.toolkit.ui.TabSheet.SelectedTabChangeEvent;
+import com.itmill.toolkit.ui.TabSheet.Tab;
public class AccordionDisabledExample extends VerticalLayout implements
Accordion.SelectedTabChangeListener, Button.ClickListener {
@@ -18,6 +19,9 @@ public class AccordionDisabledExample extends VerticalLayout implements private Label l1;
private Label l2;
private Label l3;
+ private Tab t1;
+ private Tab t2;
+ private Tab t3;
private static final ThemeResource icon1 = new ThemeResource(
"icons/action_save.gif");
@@ -36,9 +40,9 @@ public class AccordionDisabledExample extends VerticalLayout implements a = new Accordion();
a.setHeight("300px");
a.setWidth("400px");
- a.addTab(l1, "Saved actions", icon1);
- a.addTab(l2, "Notes", icon2);
- a.addTab(l3, "Issues", icon3);
+ t1 = a.addTab(l1, "Saved actions", icon1);
+ t2 = a.addTab(l2, "Notes", icon2);
+ t3 = a.addTab(l3, "Issues", icon3);
a.addListener(this);
b1 = new Button("Disable 'Notes' tab");
@@ -56,25 +60,25 @@ public class AccordionDisabledExample extends VerticalLayout implements }
public void selectedTabChange(SelectedTabChangeEvent event) {
- String c = a.getTabCaption(event.getTabSheet().getSelectedTab());
+ String c = a.getTab(event.getTabSheet().getSelectedTab()).getCaption();
getWindow().showNotification("Selected tab: " + c);
}
public void buttonClick(ClickEvent event) {
if (b1.equals(event.getButton())) { // b1 clicked
- if (l2.isEnabled()) {
- l2.setEnabled(false);
+ if (t2.isEnabled()) {
+ t2.setEnabled(false);
b1.setCaption("Enable 'Notes' tab");
} else {
- l2.setEnabled(true);
+ t2.setEnabled(true);
b1.setCaption("Disable 'Notes' tab");
}
} else { // b2 clicked
- if (l3.isVisible()) {
- l3.setVisible(false);
+ if (t3.isVisible()) {
+ t3.setVisible(false);
b2.setCaption("Show 'Issues' tab");
} else {
- l3.setVisible(true);
+ t3.setVisible(true);
b2.setCaption("Hide 'Issues' tab");
}
}
diff --git a/src/com/itmill/toolkit/demo/sampler/features/tabsheets/TabSheetDisabledExample.java b/src/com/itmill/toolkit/demo/sampler/features/tabsheets/TabSheetDisabledExample.java index 12ad969e71..13c292772e 100644 --- a/src/com/itmill/toolkit/demo/sampler/features/tabsheets/TabSheetDisabledExample.java +++ b/src/com/itmill/toolkit/demo/sampler/features/tabsheets/TabSheetDisabledExample.java @@ -8,6 +8,7 @@ import com.itmill.toolkit.ui.TabSheet; import com.itmill.toolkit.ui.VerticalLayout;
import com.itmill.toolkit.ui.Button.ClickEvent;
import com.itmill.toolkit.ui.TabSheet.SelectedTabChangeEvent;
+import com.itmill.toolkit.ui.TabSheet.Tab;
public class TabSheetDisabledExample extends VerticalLayout implements
TabSheet.SelectedTabChangeListener, Button.ClickListener {
@@ -24,6 +25,7 @@ public class TabSheetDisabledExample extends VerticalLayout implements private VerticalLayout l1;
private VerticalLayout l2;
private VerticalLayout l3;
+ private Tab t1, t2, t3;
public TabSheetDisabledExample() {
setSpacing(true);
@@ -44,9 +46,9 @@ public class TabSheetDisabledExample extends VerticalLayout implements t = new TabSheet();
t.setHeight("200px");
t.setWidth("400px");
- t.addTab(l1, "Saved actions", icon1);
- t.addTab(l2, "Notes", icon2);
- t.addTab(l3, "Issues", icon3);
+ t1 = t.addTab(l1, "Saved actions", icon1);
+ t2 = t.addTab(l2, "Notes", icon2);
+ t3 = t.addTab(l3, "Issues", icon3);
t.addListener(this);
toggleEnabled = new Button("Disable 'Notes' tab");
@@ -65,21 +67,21 @@ public class TabSheetDisabledExample extends VerticalLayout implements }
public void selectedTabChange(SelectedTabChangeEvent event) {
- String c = t.getTabCaption(event.getTabSheet().getSelectedTab());
+ String c = t.getTab(event.getTabSheet().getSelectedTab()).getCaption();
getWindow().showNotification("Selected tab: " + c);
}
public void buttonClick(ClickEvent event) {
if (toggleEnabled.equals(event.getButton())) {
// toggleEnabled clicked
- l2.setEnabled(!l2.isEnabled());
- toggleEnabled.setCaption((l2.isEnabled() ? "Disable" : "Enable")
+ t2.setEnabled(!t2.isEnabled());
+ toggleEnabled.setCaption((t2.isEnabled() ? "Disable" : "Enable")
+ " 'Notes' tab");
} else {
// toggleVisible clicked
- l3.setVisible(!l3.isVisible());
- toggleVisible.setCaption((l3.isVisible() ? "Hide" : "Show")
+ t3.setVisible(!t3.isVisible());
+ toggleVisible.setCaption((t3.isVisible() ? "Hide" : "Show")
+ " 'Issues' tab");
}
diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ComponentLocator.java b/src/com/itmill/toolkit/terminal/gwt/client/ComponentLocator.java index c4f44c9440..da4aea74e3 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ComponentLocator.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ComponentLocator.java @@ -1,5 +1,6 @@ package com.itmill.toolkit.terminal.gwt.client; +import java.util.ArrayList; import java.util.Iterator; import com.google.gwt.user.client.DOM; @@ -7,6 +8,7 @@ import com.google.gwt.user.client.Element; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.itmill.toolkit.terminal.gwt.client.ui.IView; +import com.itmill.toolkit.terminal.gwt.client.ui.IWindow; import com.itmill.toolkit.terminal.gwt.client.ui.SubPartAware; /** @@ -64,6 +66,15 @@ public class ComponentLocator { } if (e == null || pid == null) { + + // Still test for context menu option + String subPartName = client.getContextMenu().getSubPartName( + targetElement); + if (subPartName != null) { + // IContextMenu, singleton attached directly to rootpanel + return "/IContextMenu[0]" + SUBPART_SEPARATOR + subPartName; + + } return null; } @@ -217,6 +228,12 @@ public class ComponentLocator { if (w instanceof IView) { return ""; + } else if (w instanceof IWindow) { + IWindow win = (IWindow) w; + ArrayList<IWindow> subWindowList = client.getView() + .getSubWindowList(); + int indexOfSubWindow = subWindowList.indexOf(win); + return PARENTCHILD_SEPARATOR + "IWindow[" + indexOfSubWindow + "]"; } Widget parent = w.getParent(); @@ -225,7 +242,7 @@ public class ComponentLocator { String simpleName = Util.getSimpleName(w); - Iterator i = ((HasWidgets) parent).iterator(); + Iterator<Widget> i = ((HasWidgets) parent).iterator(); int pos = 0; while (i.hasNext()) { Object child = i.next(); @@ -262,12 +279,19 @@ public class ComponentLocator { } else if (w instanceof HasWidgets) { HasWidgets parent = (HasWidgets) w; - String simpleName = Util.getSimpleName(parent); + String[] split = part.split("\\["); - Iterator i = parent.iterator(); + Iterator<? extends Widget> i; + String widgetClassName = split[0]; + if (widgetClassName.equals("IWindow")) { + i = client.getView().getSubWindowList().iterator(); + } else if (widgetClassName.equals("IContextMenu")) { + return client.getContextMenu(); + } else { + i = parent.iterator(); + } boolean ok = false; - String[] split = part.split("\\["); int pos = Integer.parseInt(split[1].substring(0, split[1] .length() - 1)); // ApplicationConnection.getConsole().log( @@ -275,10 +299,10 @@ public class ComponentLocator { while (i.hasNext()) { // ApplicationConnection.getConsole().log("- child found"); - Widget child = (Widget) i.next(); + Widget child = i.next(); String simpleName2 = Util.getSimpleName(child); - if (split[0].equals(simpleName2)) { + if (widgetClassName.equals(simpleName2)) { if (pos == 0) { w = child; ok = true; diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java index 1ed82d51d4..e924dfab6b 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IAccordion.java @@ -582,18 +582,7 @@ public class IAccordion extends ITabsheetBase implements } public void updateCaption(Paintable component, UIDL uidl) { - for (Widget w : getChildren()) { - StackItem si = (StackItem) w; - if (si.getPaintable() == component) { - boolean visible = si.isVisible(); - si.updateCaption(uidl); - if (si.isCaptionVisible() != visible) { - si.setVisible(si.isCaptionVisible()); - } - - return; - } - } + /* Accordion does not render its children's captions */ } public boolean requestLayout(Set<Paintable> child) { diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IContextMenu.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IContextMenu.java index 411e646a0c..ba7f5b509b 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IContextMenu.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IContextMenu.java @@ -4,12 +4,17 @@ package com.itmill.toolkit.terminal.gwt.client.ui; +import com.google.gwt.dom.client.NodeList; +import com.google.gwt.dom.client.TableRowElement; +import com.google.gwt.dom.client.TableSectionElement; +import com.google.gwt.user.client.Element; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.MenuBar; import com.google.gwt.user.client.ui.MenuItem; import com.google.gwt.user.client.ui.PopupPanel; +import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; -public class IContextMenu extends IToolkitOverlay { +public class IContextMenu extends IToolkitOverlay implements SubPartAware { private ActionOwner actionOwner; @@ -112,4 +117,42 @@ public class IContextMenu extends IToolkitOverlay { * super.onBrowserEvent(event); } */ } + + public Element getSubPartElement(String subPart) { + int index = Integer.parseInt(subPart.substring(6)); + ApplicationConnection.getConsole().log( + "Searching element for selection index " + index); + Element wrapperdiv = menu.getElement(); + com.google.gwt.dom.client.TableSectionElement tBody = (TableSectionElement) wrapperdiv + .getFirstChildElement().getFirstChildElement(); + TableRowElement item = tBody.getRows().getItem(index); + com.google.gwt.dom.client.Element clickableDivElement = item + .getFirstChildElement().getFirstChildElement(); + return clickableDivElement.cast(); + } + + public String getSubPartName(Element subElement) { + if (getElement().isOrHasChild(subElement)) { + com.google.gwt.dom.client.Element e = subElement; + { + while (e != null && !e.getTagName().toLowerCase().equals("tr")) { + e = e.getParentElement(); + ApplicationConnection.getConsole().log("Found row"); + } + } + com.google.gwt.dom.client.TableSectionElement parentElement = (TableSectionElement) e + .getParentElement(); + NodeList<TableRowElement> rows = parentElement.getRows(); + for (int i = 0; i < rows.getLength(); i++) { + if (rows.getItem(i) == e) { + ApplicationConnection.getConsole().log( + "Found index for row" + 1); + return "option" + i; + } + } + return null; + } else { + return null; + } + } } diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java index e40b6ac0a8..f1a61edc1c 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/ITabsheet.java @@ -763,14 +763,7 @@ public class ITabsheet extends ITabsheetBase { } public void updateCaption(Paintable component, UIDL uidl) { - int i = tp.getWidgetIndex((Widget) component); - ICaption c = captions.get("" + i); - boolean visible = c.isVisible(); - c.updateCaption(uidl); - if (c.isVisible() != visible) { - tb.setVisible(i, c.isVisible()); - c.setWidth(c.getRequiredWidth() + "px"); - } + /* Tabsheet does not render its children's captions */ } public boolean requestLayout(Set<Paintable> child) { diff --git a/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java b/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java index 0c22da4a1e..b30a1eb8af 100644 --- a/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java +++ b/src/com/itmill/toolkit/terminal/gwt/client/ui/IView.java @@ -4,8 +4,10 @@ package com.itmill.toolkit.terminal.gwt.client.ui; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.Set; import com.google.gwt.dom.client.DivElement; @@ -44,7 +46,7 @@ public class IView extends SimplePanel implements Container, private Paintable layout; - private final HashSet subWindows = new HashSet(); + private final LinkedHashSet<IWindow> subWindows = new LinkedHashSet<IWindow>(); private String id; @@ -231,7 +233,8 @@ public class IView extends SimplePanel implements Container, layout.updateFromUIDL(childUidl, client); // Update subwindows - final HashSet removedSubWindows = new HashSet(subWindows); + final HashSet<IWindow> removedSubWindows = new HashSet<IWindow>( + subWindows); // Open new windows while ((childUidl = uidl.getChildUIDL(childIndex++)) != null) { @@ -240,7 +243,7 @@ public class IView extends SimplePanel implements Container, if (subWindows.contains(w)) { removedSubWindows.remove(w); } else { - subWindows.add(w); + subWindows.add((IWindow) w); } w.updateFromUIDL(childUidl, client); } else if ("actions".equals(childUidl.getTag())) { @@ -282,8 +285,9 @@ public class IView extends SimplePanel implements Container, } // Close old windows - for (final Iterator rem = removedSubWindows.iterator(); rem.hasNext();) { - final IWindow w = (IWindow) rem.next(); + for (final Iterator<IWindow> rem = removedSubWindows.iterator(); rem + .hasNext();) { + final IWindow w = rem.next(); client.unregisterPaintable(w); subWindows.remove(w); w.hide(); @@ -551,7 +555,21 @@ public class IView extends SimplePanel implements Container, } public void updateCaption(Paintable component, UIDL uidl) { - // TODO Auto-generated method stub + // NOP Subwindows never draw caption for their first child (layout) + } + + /** + * Return an iterator for current subwindows. This method is meant for + * testing purposes only. + * + * @return + */ + public ArrayList<IWindow> getSubWindowList() { + ArrayList<IWindow> windows = new ArrayList<IWindow>(subWindows.size()); + for (IWindow widget : subWindows) { + windows.add(widget); + } + return windows; } } diff --git a/src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java b/src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java new file mode 100644 index 0000000000..b43d005274 --- /dev/null +++ b/src/com/itmill/toolkit/tests/components/absolutelayout/AbsoluteLayoutClipping.java @@ -0,0 +1,42 @@ +package com.itmill.toolkit.tests.components.absolutelayout; + +import com.itmill.toolkit.tests.components.TestBase; +import com.itmill.toolkit.ui.AbsoluteLayout; +import com.itmill.toolkit.ui.Label; + +public class AbsoluteLayoutClipping extends TestBase { + + @Override + protected void setup() { + setTheme("tests-tickets"); + AbsoluteLayout abs = new AbsoluteLayout(); + abs.setStyleName("borders"); + abs.setWidth("100px"); + abs.setHeight("100px"); + + Label l = new Label("This should be clipped at 100px"); + l.setSizeUndefined(); + abs.addComponent(l, "top:50px;left:50px"); + + Label l2 = new Label("This should not be visible"); + l2.setSizeUndefined(); + abs.addComponent(l2, "top:80px;left:150px"); + + Label l3 = new Label("This should be clipped vertically at 100px"); + l3.setWidth("50px"); + abs.addComponent(l3, "top:20px;left:0px"); + + addComponent(abs); + } + + @Override + protected String getDescription() { + return "An AbsoluteLayout with fixed size should clip at its borders. Nothing outside the black square should be visible."; + } + + @Override + protected Integer getTicketNumber() { + return 2913; + } + +} diff --git a/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetCaptions.java b/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetCaptions.java index be9cfaafbb..d1b13ca00d 100644 --- a/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetCaptions.java +++ b/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetCaptions.java @@ -1,5 +1,7 @@ package com.itmill.toolkit.tests.components.tabsheet;
+import java.util.Date;
+
import com.itmill.toolkit.tests.components.TestBase;
import com.itmill.toolkit.ui.Button;
import com.itmill.toolkit.ui.Label;
@@ -25,20 +27,29 @@ public class TabSheetCaptions extends TestBase { protected void setup() {
final TabSheet tabSheet = new TabSheet();
- panel1 = new Panel("tab 1");
+ panel1 = new Panel("Panel initial caption (should also be tab caption)");
panel1.setSizeFull();
panel1.getLayout().setSizeFull();
- panel1.addComponent(new Label("This is first panel"));
+ panel1.addComponent(new Label("This is a panel"));
tabSheet.addTab(panel1);
Button button = new Button("Update tab caption");
button.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
- tabSheet.setTabCaption(panel1, "This is a new caption");
+ tabSheet.setTabCaption(panel1, "This is a new tab caption "
+ + new Date());
+ }
+ });
+
+ Button button2 = new Button("Update panel caption");
+ button2.addListener(new Button.ClickListener() {
+ public void buttonClick(ClickEvent event) {
+ panel1.setCaption("This is a new panel caption " + new Date());
}
});
addComponent(tabSheet);
addComponent(button);
+ addComponent(button2);
}
}
diff --git a/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetDisabling.java b/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetDisabling.java index f934cb0689..ecac170c3c 100644 --- a/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetDisabling.java +++ b/src/com/itmill/toolkit/tests/components/tabsheet/TabSheetDisabling.java @@ -21,7 +21,8 @@ public class TabSheetDisabling extends TestBase { new ClickListener() {
public void buttonClick(ClickEvent event) {
- event.getButton().setEnabled(false);
+ Button b = event.getButton();
+ tabSheet.getTab(b).setEnabled(false);
}
@@ -30,8 +31,8 @@ public class TabSheetDisabling extends TestBase { buttons[i] = new Button("Hide this tab", new ClickListener() {
public void buttonClick(ClickEvent event) {
- event.getButton().setVisible(false);
-
+ Button b = event.getButton();
+ tabSheet.getTab(b).setVisible(false);
}
});
diff --git a/src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java b/src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java new file mode 100644 index 0000000000..14702a75ff --- /dev/null +++ b/src/com/itmill/toolkit/tests/layouts/AbsoluteLayoutAddRemove.java @@ -0,0 +1,50 @@ +package com.itmill.toolkit.tests.layouts; + +import com.itmill.toolkit.tests.components.TestBase; +import com.itmill.toolkit.ui.AbsoluteLayout; +import com.itmill.toolkit.ui.Button; +import com.itmill.toolkit.ui.Label; +import com.itmill.toolkit.ui.Layout; +import com.itmill.toolkit.ui.Button.ClickEvent; + +public class AbsoluteLayoutAddRemove extends TestBase { + + @Override + protected String getDescription() { + return "Tests that addComponent() and removeComponent() works"; + } + + @Override + protected Integer getTicketNumber() { + return 2915; + } + + @Override + protected void setup() { + Layout main = getLayout(); + + final Label l = new Label("A Label"); + final AbsoluteLayout al = new AbsoluteLayout(); + al.setWidth("300px"); + al.setHeight("200px"); + main.addComponent(al); + + final Button b = new Button("Add", new Button.ClickListener() { + + public void buttonClick(ClickEvent event) { + if (l.getParent() == null) { + al.addComponent(l); + event.getButton().setCaption("Remove"); + } else { + al.removeComponent(l); + event.getButton().setCaption("Add"); + } + + } + + }); + main.addComponent(b); + + } + +} diff --git a/src/com/itmill/toolkit/ui/AbsoluteLayout.java b/src/com/itmill/toolkit/ui/AbsoluteLayout.java index fd5e72aff6..fbac344932 100644 --- a/src/com/itmill/toolkit/ui/AbsoluteLayout.java +++ b/src/com/itmill/toolkit/ui/AbsoluteLayout.java @@ -52,6 +52,7 @@ public class AbsoluteLayout extends AbstractLayout { public void removeComponent(Component c) { components.remove(c); super.removeComponent(c); + requestRepaint(); } public void addComponent(Component c, String cssPosition) { diff --git a/src/com/itmill/toolkit/ui/Label.java b/src/com/itmill/toolkit/ui/Label.java index 4a272ed1d1..26d4d16963 100644 --- a/src/com/itmill/toolkit/ui/Label.java +++ b/src/com/itmill/toolkit/ui/Label.java @@ -372,8 +372,10 @@ public class Label extends AbstractComponent implements Property, * the New content mode of the label. */ public void setContentMode(int contentMode) { - if (contentMode >= CONTENT_TEXT && contentMode <= CONTENT_RAW) { + if (contentMode != this.contentMode && contentMode >= CONTENT_TEXT + && contentMode <= CONTENT_RAW) { this.contentMode = contentMode; + requestRepaint(); } } diff --git a/src/com/itmill/toolkit/ui/TabSheet.java b/src/com/itmill/toolkit/ui/TabSheet.java index 5d2e9ac57f..510cf99d73 100644 --- a/src/com/itmill/toolkit/ui/TabSheet.java +++ b/src/com/itmill/toolkit/ui/TabSheet.java @@ -6,10 +6,12 @@ package com.itmill.toolkit.ui; import java.io.Serializable; import java.lang.reflect.Method; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; +import com.itmill.toolkit.terminal.ErrorMessage; import com.itmill.toolkit.terminal.KeyMapper; import com.itmill.toolkit.terminal.PaintException; import com.itmill.toolkit.terminal.PaintTarget; @@ -31,7 +33,12 @@ public class TabSheet extends AbstractComponentContainer implements /** * Linked list of component tabs. */ - private final LinkedList tabs = new LinkedList(); + private final LinkedList components = new LinkedList(); + + /** + * Map containing information related to the tabs (caption, icon etc). + */ + private final HashMap<Component, Tab> tabs = new HashMap<Component, Tab>(); /** * Selected tab. @@ -64,7 +71,7 @@ public class TabSheet extends AbstractComponentContainer implements * @return the Iterator of the components inside the container. */ public Iterator getComponentIterator() { - return java.util.Collections.unmodifiableList(tabs).iterator(); + return java.util.Collections.unmodifiableList(components).iterator(); } /** @@ -75,15 +82,16 @@ public class TabSheet extends AbstractComponentContainer implements */ @Override public void removeComponent(Component c) { - if (c != null && tabs.contains(c)) { + if (c != null && components.contains(c)) { super.removeComponent(c); keyMapper.remove(c); + components.remove(c); tabs.remove(c); if (c.equals(selected)) { - if (tabs.isEmpty()) { + if (components.isEmpty()) { selected = null; } else { - selected = (Component) tabs.getFirst(); + selected = (Component) components.getFirst(); fireSelectedTabChange(); } } @@ -114,16 +122,23 @@ public class TabSheet extends AbstractComponentContainer implements * @param icon * the icon to be set for the component and used rendered in tab * bar + * @return the created tab */ - public void addTab(Component c, String caption, Resource icon) { + public Tab addTab(Component c, String caption, Resource icon) { if (c != null) { - if (caption != null) { - c.setCaption(caption); - } - if (icon != null) { - c.setIcon(icon); + components.addLast(c); + Tab tab = new TabSheetTabImpl(caption, icon); + + tabs.put(c, tab); + if (selected == null) { + selected = c; + fireSelectedTabChange(); } - addTab(c); + super.addComponent(c); + requestRepaint(); + return tab; + } else { + return null; } } @@ -133,17 +148,13 @@ public class TabSheet extends AbstractComponentContainer implements * * @param c * the component to be added onto tab. + * @return the created tab */ - public void addTab(Component c) { + public Tab addTab(Component c) { if (c != null) { - tabs.addLast(c); - if (selected == null) { - selected = c; - fireSelectedTabChange(); - } - super.addComponent(c); - requestRepaint(); + return addTab(c, c.getCaption(), c.getIcon()); } + return null; } /** @@ -197,54 +208,70 @@ public class TabSheet extends AbstractComponentContainer implements target.startTag("tabs"); for (final Iterator i = getComponentIterator(); i.hasNext();) { - final Component c = (Component) i.next(); + final Component component = (Component) i.next(); + Tab tab = tabs.get(component); /* * If we have no selection, if the current selection is invisible or * if the current selection is disabled (but the whole component is * not) we select this tab instead */ - if (selected == null || !selected.isVisible() - || (!selected.isEnabled() && isEnabled())) { - selected = c; + Tab selectedTabInfo = null; + if (selected != null) { + selectedTabInfo = tabs.get(selected); + } + if (selected == null || selectedTabInfo == null + || !selectedTabInfo.isVisible() + || !selectedTabInfo.isEnabled()) { + + // The current selection is not valid so we need to change it + if (tab.isEnabled() && tab.isVisible()) { + selected = component; + } else { + /* + * The current selection is not valid but this tab cannot be + * selected either. + */ + selected = null; + } } target.startTag("tab"); - if (!c.isEnabled() && c.isVisible()) { + if (!tab.isEnabled() && tab.isVisible()) { target.addAttribute("disabled", true); } - if (!c.isVisible()) { + if (!tab.isVisible()) { target.addAttribute("hidden", true); } - final Resource icon = getTabIcon(c); + final Resource icon = tab.getIcon(); if (icon != null) { target.addAttribute("icon", icon); } - final String caption = getTabCaption(c); + final String caption = tab.getCaption(); if (caption != null && caption.length() > 0) { target.addAttribute("caption", caption); } - if (c instanceof AbstractComponent) { - AbstractComponent ac = (AbstractComponent) c; - if (ac.getDescription() != null) { - target.addAttribute("description", ac.getDescription()); - } - if (ac.getComponentError() != null) { - ac.getComponentError().paint(target); - } + final String description = tab.getDescription(); + if (description != null) { + target.addAttribute("description", description); } - target.addAttribute("key", keyMapper.key(c)); - if (c.equals(selected)) { + final ErrorMessage componentError = tab.getComponentError(); + if (componentError != null) { + componentError.paint(target); + } + + target.addAttribute("key", keyMapper.key(component)); + if (component.equals(selected)) { target.addAttribute("selected", true); - c.paint(target); - paintedTabs.add(c); - } else if (paintedTabs.contains(c)) { - c.paint(target); + component.paint(target); + paintedTabs.add(component); + } else if (paintedTabs.contains(component)) { + component.paint(target); } else { - c.requestRepaintRequests(); + component.requestRepaintRequests(); } target.endTag("tab"); } @@ -281,12 +308,16 @@ public class TabSheet extends AbstractComponentContainer implements * * @param c * the component. + * @deprecated Use {@link #getTab(Component)} and {@link Tab#getCaption()} + * instead. */ + @Deprecated public String getTabCaption(Component c) { - if (c.getCaption() == null) { + Tab info = tabs.get(c); + if (info == null) { return ""; } else { - return c.getCaption(); + return info.getCaption(); } } @@ -297,10 +328,15 @@ public class TabSheet extends AbstractComponentContainer implements * the component. * @param caption * the caption to set. + * @deprecated Use {@link #getTab(Component)} and + * {@link Tab#setCaption(String)} instead. */ + @Deprecated public void setTabCaption(Component c, String caption) { - if (tabs.contains(c)) { - c.setCaption(caption); + Tab info = tabs.get(c); + if (info != null) { + info.setCaption(caption); + requestRepaint(); } } @@ -309,32 +345,59 @@ public class TabSheet extends AbstractComponentContainer implements * * @param c * the component. + * @deprecated Use {@link #getTab(Component)} and {@link Tab#getIcon()} + * instead. */ + @Deprecated public Resource getTabIcon(Component c) { - return c.getIcon(); + Tab info = tabs.get(c); + if (info == null) { + return null; + } else { + return info.getIcon(); + } } /** - * Sets overridden icon for given component. + * Sets icon for the given component. * * Normally TabSheet uses icon from component * * @param c + * the component * @param icon + * the icon to set + * @deprecated Use {@link #getTab(Component)} and + * {@link Tab#setIcon(Resource)} instead. */ + @Deprecated public void setTabIcon(Component c, Resource icon) { - if (tabs.contains(c)) { - c.setIcon(icon); + Tab info = tabs.get(c); + if (info != null) { + info.setIcon(icon); + requestRepaint(); } } /** + * Returns the Tab for the component. The Tab object can be used for setting + * caption,icon, etc for the tab. + * + * @param c + * the component + * @return + */ + public Tab getTab(Component c) { + return tabs.get(c); + } + + /** * Sets the selected tab. * * @param c */ public void setSelectedTab(Component c) { - if (c != null && tabs.contains(c) && !selected.equals(c)) { + if (c != null && components.contains(c) && !selected.equals(c)) { selected = c; fireSelectedTabChange(); requestRepaint(); @@ -372,17 +435,33 @@ public class TabSheet extends AbstractComponentContainer implements selected = newComponent; } + Tab newTab = tabs.get(newComponent); + Tab oldTab = tabs.get(oldComponent); + // Gets the captions - final String oldCaption = getTabCaption(oldComponent); - final Resource oldIcon = getTabIcon(oldComponent); - final String newCaption = getTabCaption(newComponent); - final Resource newIcon = getTabIcon(newComponent); + String oldCaption = null; + Resource oldIcon = null; + String newCaption = null; + Resource newIcon = null; + + if (oldTab != null) { + oldCaption = oldTab.getCaption(); + oldIcon = oldTab.getIcon(); + } + + if (newTab != null) { + newCaption = newTab.getCaption(); + newIcon = newTab.getIcon(); + } else { + newCaption = newComponent.getCaption(); + newIcon = newComponent.getIcon(); + } // Gets the locations int oldLocation = -1; int newLocation = -1; int location = 0; - for (final Iterator i = tabs.iterator(); i.hasNext();) { + for (final Iterator i = components.iterator(); i.hasNext();) { final Component component = (Component) i.next(); if (component == oldComponent) { @@ -400,27 +479,34 @@ public class TabSheet extends AbstractComponentContainer implements } else if (newLocation == -1) { removeComponent(oldComponent); keyMapper.remove(oldComponent); - addComponent(newComponent); - tabs.remove(newComponent); - tabs.add(oldLocation, newComponent); - setTabCaption(newComponent, oldCaption); - setTabIcon(newComponent, oldIcon); + newTab = addTab(newComponent); + components.remove(newComponent); + components.add(oldLocation, newComponent); + newTab.setCaption(oldCaption); + newTab.setIcon(oldIcon); } else { if (oldLocation > newLocation) { - tabs.remove(oldComponent); - tabs.add(newLocation, oldComponent); - tabs.remove(newComponent); - tabs.add(oldLocation, newComponent); + components.remove(oldComponent); + components.add(newLocation, oldComponent); + components.remove(newComponent); + components.add(oldLocation, newComponent); } else { - tabs.remove(newComponent); - tabs.add(oldLocation, newComponent); - tabs.remove(oldComponent); - tabs.add(newLocation, oldComponent); + components.remove(newComponent); + components.add(oldLocation, newComponent); + components.remove(oldComponent); + components.add(newLocation, oldComponent); + } + + if (newTab != null) { + // This should always be true + newTab.setCaption(oldCaption); + newTab.setIcon(oldIcon); + } + if (oldTab != null) { + // This should always be true + oldTab.setCaption(newCaption); + oldTab.setIcon(newIcon); } - setTabCaption(newComponent, oldCaption); - setTabIcon(newComponent, oldIcon); - setTabCaption(oldComponent, newCaption); - setTabIcon(oldComponent, newIcon); requestRepaint(); } @@ -538,4 +624,167 @@ public class TabSheet extends AbstractComponentContainer implements paintedTabs.clear(); } + /** + * + */ + public interface Tab extends Serializable { + /** + * Returns the visible status for the tab. + * + * @return true for visible, false for hidden + */ + public boolean isVisible(); + + /** + * Sets the visible status for the tab. + * + * @param visible + * true for visible, false for hidden + */ + public void setVisible(boolean visible); + + /** + * Returns the enabled status for the tab. + * + * @return true for enabled, false for disabled + */ + public boolean isEnabled(); + + /** + * Sets the enabled status for the tab. + * + * @param enabled + * true for enabled, false for disabled + */ + public void setEnabled(boolean enabled); + + /** + * Sets the caption for the tab. + * + * @param caption + * the caption to set + */ + public void setCaption(String caption); + + /** + * Gets the caption for the tab. + * + */ + public String getCaption(); + + /** + * Gets the icon for the tab. + * + */ + public Resource getIcon(); + + /** + * Sets the icon for the tab. + * + * @param icon + * the icon to set + */ + public void setIcon(Resource icon); + + /** + * Gets the description for the tab. The description can be used to + * briefly describe the state of the tab to the user. + * + * @return the description for the tab + */ + public String getDescription(); + + /** + * Sets the description for the tab. + * + * @param description + * the new description string for the tab. + */ + public void setDescription(String description); + + public void setComponentError(ErrorMessage componentError); + + public ErrorMessage getComponentError(); + + } + + /** + * TabSheet's implementation of Tab + * + */ + public class TabSheetTabImpl implements Tab { + + private String caption = ""; + private Resource icon = null; + private boolean enabled = true; + private boolean visible = true; + private String description = null; + private ErrorMessage componentError = null; + + public TabSheetTabImpl(String caption, Resource icon) { + if (caption == null) { + caption = ""; + } + this.caption = caption; + this.icon = icon; + } + + /** + * Returns the tab caption. Can never be null. + */ + public String getCaption() { + return caption; + } + + public void setCaption(String caption) { + this.caption = caption; + requestRepaint(); + } + + public Resource getIcon() { + return icon; + } + + public void setIcon(Resource icon) { + this.icon = icon; + requestRepaint(); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + requestRepaint(); + } + + public boolean isVisible() { + return visible; + } + + public void setVisible(boolean visible) { + this.visible = visible; + requestRepaint(); + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + requestRepaint(); + } + + public ErrorMessage getComponentError() { + return componentError; + } + + public void setComponentError(ErrorMessage componentError) { + this.componentError = componentError; + requestRepaint(); + } + + } } |