summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin/ui
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/vaadin/ui')
-rw-r--r--src/com/vaadin/ui/Button.java8
-rw-r--r--src/com/vaadin/ui/DateField.java42
-rw-r--r--src/com/vaadin/ui/LoginForm.java4
-rw-r--r--src/com/vaadin/ui/MenuBar.java162
-rw-r--r--src/com/vaadin/ui/TabSheet.java108
-rw-r--r--src/com/vaadin/ui/Upload.java2
-rw-r--r--src/com/vaadin/ui/Window.java50
7 files changed, 315 insertions, 61 deletions
diff --git a/src/com/vaadin/ui/Button.java b/src/com/vaadin/ui/Button.java
index 6801bfa176..3ed50b2d42 100644
--- a/src/com/vaadin/ui/Button.java
+++ b/src/com/vaadin/ui/Button.java
@@ -36,7 +36,7 @@ public class Button extends AbstractField {
*
*/
public Button() {
- setValue(new Boolean(false));
+ setValue(Boolean.FALSE);
setSwitchMode(false);
}
@@ -96,7 +96,7 @@ public class Button extends AbstractField {
*/
public Button(String caption, boolean initialState) {
setCaption(caption);
- setValue(new Boolean(initialState));
+ setValue(Boolean.valueOf(initialState));
setSwitchMode(true);
}
@@ -167,7 +167,7 @@ public class Button extends AbstractField {
// If the button is true for some reason, release it
if (oldValue.booleanValue()) {
- setValue(new Boolean(false));
+ setValue(Boolean.FALSE);
}
}
}
@@ -194,7 +194,7 @@ public class Button extends AbstractField {
if (!switchMode) {
setImmediate(true);
if (booleanValue()) {
- setValue(new Boolean(false));
+ setValue(Boolean.FALSE);
}
}
}
diff --git a/src/com/vaadin/ui/DateField.java b/src/com/vaadin/ui/DateField.java
index 69d6108152..425040a016 100644
--- a/src/com/vaadin/ui/DateField.java
+++ b/src/com/vaadin/ui/DateField.java
@@ -116,6 +116,8 @@ public class DateField extends AbstractField {
*/
private String dateString;
+ private boolean lenient = false;
+
/* Constructors */
/**
@@ -202,6 +204,10 @@ public class DateField extends AbstractField {
target.addAttribute("format", dateFormat);
}
+ if (!isLenient()) {
+ target.addAttribute("strict", true);
+ }
+
target.addAttribute("type", type);
// Gets the calendar
@@ -332,13 +338,13 @@ public class DateField extends AbstractField {
newDate = cal.getTime();
}
- if (newDate != oldDate
+ if (newDate == null && dateString != null && !"".equals(dateString)
+ && !dateString.equals(oldDateString)) {
+ setValue(handleUnparsableDateString(dateString));
+ } else if (newDate != oldDate
&& (newDate == null || !newDate.equals(oldDate))) {
setValue(newDate, true); // Don't require a repaint, client
// updates itself
- } else if (dateString != null && !"".equals(dateString)
- && !dateString.equals(oldDateString)) {
- setValue(handleUnparsableDateString(dateString));
}
}
}
@@ -511,4 +517,32 @@ public class DateField extends AbstractField {
return dateFormat;
}
+ /**
+ * Specifies whether or not date/time interpretation in component is to be
+ * lenient.
+ *
+ * @see Calendar#setLenient(boolean)
+ * @see #isLenient()
+ *
+ * @param lenient
+ * true if the lenient mode is to be turned on; false if it is to
+ * be turned off.
+ */
+ public void setLenient(boolean lenient) {
+ this.lenient = lenient;
+ requestRepaint();
+ }
+
+ /**
+ * Specifies whether or not date/time interpretation is to be lenient.
+ *
+ * @see #setLenient(boolean)
+ *
+ * @return true if the interpretation mode of this calendar is lenient;
+ * false otherwise.
+ */
+ public boolean isLenient() {
+ return lenient;
+ }
+
}
diff --git a/src/com/vaadin/ui/LoginForm.java b/src/com/vaadin/ui/LoginForm.java
index 33ee670f4b..76c567dc5e 100644
--- a/src/com/vaadin/ui/LoginForm.java
+++ b/src/com/vaadin/ui/LoginForm.java
@@ -161,12 +161,14 @@ public class LoginForm extends CustomComponent {
+ "document.getElementsByTagName('head')[0].appendChild(stylesheet);\n"
+ "}"
+ "}\n"
+ + "function submitOnEnter(e) { var keycode = e.keyCode || e.which;"
+ + " if (keycode == 13) {document.forms[0].submit();} } \n"
+ "</script>"
+ "</head><body onload='setTarget();' style='margin:0;padding:0; background:transparent;' class=\"v-generated-body\">"
+ "<div class='v-app v-app-loginpage' style=\"background:transparent;\">"
+ "<iframe name='logintarget' style='width:0;height:0;"
+ "border:0;margin:0;padding:0;'></iframe>"
- + "<form id='loginf' target='logintarget'>"
+ + "<form id='loginf' target='logintarget' onkeypress=\"submitOnEnter(event)\">"
+ "<div>Username</div><div >"
+ "<input class='v-textfield' style='display:block;' type='text' name='username'></div>"
+ "<div>Password</div>"
diff --git a/src/com/vaadin/ui/MenuBar.java b/src/com/vaadin/ui/MenuBar.java
index 30049431d3..5715e230c4 100644
--- a/src/com/vaadin/ui/MenuBar.java
+++ b/src/com/vaadin/ui/MenuBar.java
@@ -29,8 +29,20 @@ public class MenuBar extends AbstractComponent {
// Number of items in this menu
private static int numberOfItems = 0;
+ /**
+ * @deprecated
+ * @see #setCollapse(boolean)
+ */
+ @Deprecated
private boolean collapseItems;
+
+ /**
+ * @deprecated
+ * @see #setSubmenuIcon(Resource)
+ */
+ @Deprecated
private Resource submenuIcon;
+
private MenuItem moreItem;
/** Paint (serialise) the component for the client. */
@@ -49,9 +61,7 @@ public class MenuBar extends AbstractComponent {
target.addAttribute("submenuIcon", submenuIcon);
}
- target.addAttribute("collapseItems", collapseItems);
-
- if (collapseItems) {
+ if (getWidth() > -1) {
target.startTag("moreItem");
target.addAttribute("text", moreItem.getText());
if (moreItem.getIcon() != null) {
@@ -69,31 +79,43 @@ public class MenuBar extends AbstractComponent {
while (itr.hasNext()) {
MenuItem item = itr.next();
+ if (!item.isVisible()) {
+ continue;
+ }
target.startTag("item");
-
- target.addAttribute("text", item.getText());
target.addAttribute("id", item.getId());
- Command command = item.getCommand();
- if (command != null) {
- target.addAttribute("command", true);
+ if (item.isSeparator()) {
+ target.addAttribute("separator", true);
+ target.endTag("item");
} else {
- target.addAttribute("command", false);
- }
+ target.addAttribute("text", item.getText());
- Resource icon = item.getIcon();
- if (icon != null) {
- target.addAttribute("icon", icon);
- }
+ Command command = item.getCommand();
+ if (command != null) {
+ target.addAttribute("command", true);
+ }
+
+ Resource icon = item.getIcon();
+ if (icon != null) {
+ target.addAttribute("icon", icon);
+ }
+
+ if (!item.isEnabled()) {
+ target.addAttribute("disabled", true);
+ }
- if (item.hasChildren()) {
- iteratorStack.push(itr); // For later use
+ if (item.hasChildren()) {
+ iteratorStack.push(itr); // For later use
+
+ // Go through the children
+ itr = item.getChildren().iterator();
+ } else {
+ target.endTag("item"); // Item had no children, end
+ // description
+ }
- // Go through the children
- itr = item.getChildren().iterator();
- } else {
- target.endTag("item"); // Item had no children, end description
}
// The end submenu. More than one submenu may end at once.
@@ -101,7 +123,6 @@ public class MenuBar extends AbstractComponent {
itr = iteratorStack.pop();
target.endTag("item");
}
-
}
target.endTag("items");
@@ -138,7 +159,7 @@ public class MenuBar extends AbstractComponent {
}// while
// If we got the clicked item, launch the command.
- if (found) {
+ if (found && tmpItem.isEnabled()) {
tmpItem.getCommand().menuSelected(tmpItem);
}
}// if
@@ -270,40 +291,46 @@ public class MenuBar extends AbstractComponent {
* Set the icon to be used if a sub-menu has children. Defaults to null;
*
* @param icon
+ * @deprecated (since 6.2, will be removed in 7.0) Icon is set in theme, no
+ * need to worry about the visual representation here.
*/
+ @Deprecated
public void setSubmenuIcon(Resource icon) {
submenuIcon = icon;
requestRepaint();
}
/**
- * Get the icon used for sub-menus. Returns null if no icon is set.
- *
- * @return
+ * @deprecated
+ * @see #setSubmenuIcon(Resource)
*/
+ @Deprecated
public Resource getSubmenuIcon() {
return submenuIcon;
}
/**
* Enable or disable collapsing top-level items. Top-level items will
- * collapse to if there is not enough room for them. Items that don't fit
- * will be placed under the "More" menu item.
+ * collapse together if there is not enough room for them. Items that don't
+ * fit will be placed under the "More" menu item.
*
* Collapsing is enabled by default.
*
* @param collapse
+ * @deprecated (since 6.2, will be removed in 7.0) Collapsing is always
+ * enabled if the MenuBar has a specified width.
*/
+ @Deprecated
public void setCollapse(boolean collapse) {
collapseItems = collapse;
requestRepaint();
}
/**
- * Collapsing is enabled by default.
- *
- * @return true if the top-level items will be collapsed
+ * @see #setCollapse(boolean)
+ * @deprecated
*/
+ @Deprecated
public boolean getCollapse() {
return collapseItems;
}
@@ -311,8 +338,9 @@ public class MenuBar extends AbstractComponent {
/**
* Set the item that is used when collapsing the top level menu. All
* "overflowing" items will be added below this. The item command will be
- * ignored. If set to null, the default item with the "More" text is be
- * used.
+ * ignored. If set to null, the default item with a downwards arrow is used.
+ *
+ * The item command (if specified) is ignored.
*
* @param item
*/
@@ -320,7 +348,7 @@ public class MenuBar extends AbstractComponent {
if (item != null) {
moreItem = item;
} else {
- moreItem = new MenuItem("More", null, null);
+ moreItem = new MenuItem("", null, null);
}
requestRepaint();
}
@@ -360,6 +388,9 @@ public class MenuBar extends AbstractComponent {
private List<MenuItem> itsChildren;
private Resource itsIcon;
private MenuItem itsParent;
+ private boolean enabled = true;
+ private boolean visible = true;
+ private boolean isSeparator = false;
/**
* Constructs a new menu item that can optionally have an icon and a
@@ -388,7 +419,27 @@ public class MenuBar extends AbstractComponent {
* @return True if this item has children
*/
public boolean hasChildren() {
- return itsChildren != null;
+ return !isSeparator() && itsChildren != null;
+ }
+
+ /**
+ * Adds a separator to this menu. A separator is a way to visually group
+ * items in a menu, to make it easier for users to find what they are
+ * looking for in the menu.
+ *
+ * @author Jouni Koivuviita / IT Mill Ltd.
+ * @since 6.2.0
+ */
+ public MenuBar.MenuItem addSeparator() {
+ MenuItem item = addItem("", null, null);
+ item.setSeparator(true);
+ return item;
+ }
+
+ public MenuBar.MenuItem addSeparatorBefore(MenuItem itemToAddBefore) {
+ MenuItem item = addItemBefore("", null, null, itemToAddBefore);
+ item.setSeparator(true);
+ return item;
}
/**
@@ -417,8 +468,12 @@ public class MenuBar extends AbstractComponent {
*/
public MenuBar.MenuItem addItem(String caption, Resource icon,
MenuBar.Command command) {
+ if (isSeparator()) {
+ throw new UnsupportedOperationException(
+ "Cannot add items to a separator");
+ }
if (caption == null) {
- throw new IllegalArgumentException("caption cannot be null");
+ throw new IllegalArgumentException("Caption cannot be null");
}
if (itsChildren == null) {
@@ -461,7 +516,6 @@ public class MenuBar extends AbstractComponent {
newItem = new MenuItem(caption, icon, command);
newItem.setParent(this);
itsChildren.add(index, newItem);
-
} else {
newItem = addItem(caption, icon, command);
}
@@ -524,7 +578,10 @@ public class MenuBar extends AbstractComponent {
* @return The number of child items
*/
public int getSize() {
- return itsChildren.size();
+ if (itsChildren != null) {
+ return itsChildren.size();
+ }
+ return -1;
}
/**
@@ -582,8 +639,8 @@ public class MenuBar extends AbstractComponent {
if (itsChildren.isEmpty()) {
itsChildren = null;
}
+ requestRepaint();
}
- requestRepaint();
}
/**
@@ -593,8 +650,8 @@ public class MenuBar extends AbstractComponent {
if (itsChildren != null) {
itsChildren.clear();
itsChildren = null;
+ requestRepaint();
}
- requestRepaint();
}
/**
@@ -607,6 +664,33 @@ public class MenuBar extends AbstractComponent {
itsParent = parent;
}
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ requestRepaint();
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ requestRepaint();
+ }
+
+ public boolean isVisible() {
+ return visible;
+ }
+
+ private void setSeparator(boolean isSeparator) {
+ this.isSeparator = isSeparator;
+ requestRepaint();
+ }
+
+ public boolean isSeparator() {
+ return isSeparator;
+ }
+
}// class MenuItem
}// class MenuBar
diff --git a/src/com/vaadin/ui/TabSheet.java b/src/com/vaadin/ui/TabSheet.java
index ed81fdb655..b58e7be7bf 100644
--- a/src/com/vaadin/ui/TabSheet.java
+++ b/src/com/vaadin/ui/TabSheet.java
@@ -35,7 +35,7 @@ public class TabSheet extends AbstractComponentContainer implements
/**
* Linked list of component tabs.
*/
- private final LinkedList components = new LinkedList();
+ private final LinkedList<Component> components = new LinkedList<Component>();
/**
* Map containing information related to the tabs (caption, icon etc).
@@ -54,7 +54,9 @@ public class TabSheet extends AbstractComponentContainer implements
*/
private boolean tabsHidden;
- private LinkedList paintedTabs = new LinkedList();
+ private LinkedList<Component> paintedTabs = new LinkedList<Component>();
+
+ private CloseHandler closeHandler;
/**
* Constructs a new Tabsheet. Tabsheet is immediate by default.
@@ -64,6 +66,11 @@ public class TabSheet extends AbstractComponentContainer implements
// expand horizontally by default
setWidth(100, UNITS_PERCENTAGE);
setImmediate(true);
+ setCloseHandler(new CloseHandler() {
+ public void onTabClose(TabSheet tabsheet, Component c) {
+ tabsheet.removeComponent(c);
+ }
+ });
}
/**
@@ -72,7 +79,7 @@ public class TabSheet extends AbstractComponentContainer implements
*
* @return the Iterator of the components inside the container.
*/
- public Iterator getComponentIterator() {
+ public Iterator<Component> getComponentIterator() {
return java.util.Collections.unmodifiableList(components).iterator();
}
@@ -93,7 +100,7 @@ public class TabSheet extends AbstractComponentContainer implements
if (components.isEmpty()) {
selected = null;
} else {
- selected = (Component) components.getFirst();
+ selected = components.getFirst();
fireSelectedTabChange();
}
}
@@ -168,8 +175,9 @@ public class TabSheet extends AbstractComponentContainer implements
*/
@Override
public void moveComponentsFrom(ComponentContainer source) {
- for (final Iterator i = source.getComponentIterator(); i.hasNext();) {
- final Component c = (Component) i.next();
+ for (final Iterator<Component> i = source.getComponentIterator(); i
+ .hasNext();) {
+ final Component c = i.next();
String caption = null;
Resource icon = null;
if (TabSheet.class.isAssignableFrom(source.getClass())) {
@@ -199,8 +207,8 @@ public class TabSheet extends AbstractComponentContainer implements
target.startTag("tabs");
- for (final Iterator i = getComponentIterator(); i.hasNext();) {
- final Component component = (Component) i.next();
+ for (final Iterator<Component> i = getComponentIterator(); i.hasNext();) {
+ final Component component = i.next();
Tab tab = tabs.get(component);
/*
@@ -236,6 +244,10 @@ public class TabSheet extends AbstractComponentContainer implements
target.addAttribute("hidden", true);
}
+ if (tab.isClosable()) {
+ target.addAttribute("closable", true);
+ }
+
final Resource icon = tab.getIcon();
if (icon != null) {
target.addAttribute("icon", icon);
@@ -417,6 +429,13 @@ public class TabSheet extends AbstractComponentContainer implements
setSelectedTab((Component) keyMapper.get((String) variables
.get("selected")));
}
+ if (variables.containsKey("close")) {
+ final Component tab = (Component) keyMapper.get((String) variables
+ .get("close"));
+ if (tab != null) {
+ closeHandler.onTabClose(this, tab);
+ }
+ }
}
/* Documented in superclass */
@@ -453,8 +472,8 @@ public class TabSheet extends AbstractComponentContainer implements
int oldLocation = -1;
int newLocation = -1;
int location = 0;
- for (final Iterator i = components.iterator(); i.hasNext();) {
- final Component component = (Component) i.next();
+ for (final Iterator<Component> i = components.iterator(); i.hasNext();) {
+ final Component component = i.next();
if (component == oldComponent) {
oldLocation = location;
@@ -636,6 +655,23 @@ public class TabSheet extends AbstractComponentContainer implements
public void setVisible(boolean visible);
/**
+ * Returns the closability status for the tab.
+ *
+ * @return true if the tab is allowed to be closed by the end user,
+ * false for not allowing closing
+ */
+ public boolean isClosable();
+
+ /**
+ * Sets the closability status for the tab.
+ *
+ * @param visible
+ * true if the end user is allowed to close the tab, false
+ * for not allowing to close. Should default to false.
+ */
+ public void setClosable(boolean closable);
+
+ /**
* Returns the enabled status for the tab.
*
* @return true for enabled, false for disabled
@@ -710,6 +746,7 @@ public class TabSheet extends AbstractComponentContainer implements
private Resource icon = null;
private boolean enabled = true;
private boolean visible = true;
+ private boolean closable = false;
private String description = null;
private ErrorMessage componentError = null;
@@ -760,6 +797,19 @@ public class TabSheet extends AbstractComponentContainer implements
requestRepaint();
}
+ public boolean isClosable() {
+ return closable;
+ }
+
+ public void setClosable(boolean closable) {
+ this.closable = closable;
+ requestRepaint();
+ }
+
+ public void close() {
+
+ }
+
public String getDescription() {
return description;
}
@@ -777,6 +827,44 @@ public class TabSheet extends AbstractComponentContainer implements
this.componentError = componentError;
requestRepaint();
}
+ }
+
+ /**
+ * CloseHandler is used to process tab closing events. Default behavior is
+ * to remove the tab from the TabSheet.
+ *
+ * @author Jouni Koivuviita / IT Mill Ltd.
+ * @since 6.2.0
+ *
+ */
+ public interface CloseHandler {
+ /**
+ * Called when a user has pressed the close icon of a tab in the client
+ * side widget.
+ *
+ * @param tabsheet
+ * the TabSheet to which the tab belongs to
+ * @param tabContent
+ * the component that corresponds to the tab whose close
+ * button was clicked
+ */
+ void onTabClose(final TabSheet tabsheet, final Component tabContent);
+ }
+
+ /**
+ * Provide a custom {@link CloseHandler} for this TabSheet if you wish to
+ * perform some additional tasks when a user clicks on a tabs close button,
+ * e.g. show a confirmation dialogue before removing the tab.
+ *
+ * To remove the tab, if you provide your own close handler, you must call
+ * {@link #removeComponent(Component)} yourself.
+ *
+ * The default CloseHandler for TabSheet will only remove the tab.
+ *
+ * @param handler
+ */
+ public void setCloseHandler(CloseHandler handler) {
+ closeHandler = handler;
}
}
diff --git a/src/com/vaadin/ui/Upload.java b/src/com/vaadin/ui/Upload.java
index dfbbbfc103..e3512a4795 100644
--- a/src/com/vaadin/ui/Upload.java
+++ b/src/com/vaadin/ui/Upload.java
@@ -244,8 +244,6 @@ public class Upload extends AbstractComponent implements Component.Focusable {
target.addAttribute("buttoncaption", buttonCaption);
- target.addVariable(this, "fake", true);
-
target.addUploadStreamVariable(this, "stream");
}
diff --git a/src/com/vaadin/ui/Window.java b/src/com/vaadin/ui/Window.java
index dc1bf7e18f..d234f7aaac 100644
--- a/src/com/vaadin/ui/Window.java
+++ b/src/com/vaadin/ui/Window.java
@@ -8,6 +8,7 @@ import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
@@ -119,6 +120,8 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
private Focusable pendingFocus;
+ private ArrayList<String> jsExecQueue = null;
+
/* ********************************************************************* */
/**
@@ -381,7 +384,7 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
if (getParent() != null) {
// this is subwindow
Window mainWindow = (Window) getParent();
- mainWindow.addParameterHandler(handler);
+ mainWindow.removeParameterHandler(handler);
} else {
if (handler == null || parameterHandlerList == null) {
return;
@@ -520,6 +523,16 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
// Contents of the window panel is painted
super.paintContent(target);
+ // Add executable javascripts if needed
+ if (jsExecQueue != null) {
+ for (String script : jsExecQueue) {
+ target.startTag("execJS");
+ target.addAttribute("script", script);
+ target.endTag("execJS");
+ }
+ jsExecQueue = null;
+ }
+
// Window position
target.addVariable(this, "positionx", getPositionX());
target.addVariable(this, "positiony", getPositionY());
@@ -1632,4 +1645,39 @@ public class Window extends Panel implements URIHandler, ParameterHandler {
}
}
+ /**
+ * Executes JavaScript in this window.
+ *
+ * <p>
+ * This method allows one to inject javascript from the server to client. A
+ * client implementation is not required to implement this functionality,
+ * but currently all web-based clients do implement this.
+ * </p>
+ *
+ * <p>
+ * Executing javascript this way often leads to cross-browser compatibility
+ * issues and regressions that are hard to resolve. Use of this method
+ * should be avoided and instead it is recommended to create new widgets
+ * with GWT. For more info on creating own, reusable client-side widgets in
+ * Java, read the corresponding chapter in Book of Vaadin.
+ * </p>
+ *
+ * @param script
+ * JavaScript snippet that will be executed.
+ */
+ public void executeJavaScript(String script) {
+
+ if (getParent() != null) {
+ throw new UnsupportedOperationException(
+ "Only application level windows can execute javascript.");
+ }
+
+ if (jsExecQueue == null) {
+ jsExecQueue = new ArrayList<String>();
+ }
+
+ jsExecQueue.add(script);
+
+ requestRepaint();
+ }
}