Bläddra i källkod

Large pile of various optimizations and small bug fixes. Changeset has a great regression risk, blame me on new odd bugs.

 * default alignments/expandratios now not transported over uidl
 * added new map type to painttarget
 * rewrote UIDL with overlay type
 * ditched gwt JSON implementation instead of own "overlay type" altogether
 * using arraylist instead of vector in all places on client side
 * optimized a bit LocaleService
 * rewrote uidl browsers in debug window (now does not stall IE that easily with large changesets)
 

svn changeset:8516/svn branch:6.1
tags/6.7.0.beta1
Matti Tahvonen 14 år sedan
förälder
incheckning
58ca7c6ce1

+ 12
- 1
src/com/vaadin/terminal/PaintTarget.java Visa fil

@@ -5,6 +5,7 @@
package com.vaadin.terminal;

import java.io.Serializable;
import java.util.Map;

/**
* This interface defines the methods for painting XML to the UIDL stream.
@@ -14,7 +15,7 @@ import java.io.Serializable;
* @VERSION@
* @since 3.0
*/
public interface PaintTarget extends Serializable{
public interface PaintTarget extends Serializable {

/**
* Prints single XMLsection.
@@ -201,6 +202,16 @@ public interface PaintTarget extends Serializable{
*/
public void addAttribute(String name, String value) throws PaintException;

/**
* TODO
*
* @param name
* @param value
* @throws PaintException
*/
public void addAttribute(String name, Map<?, ?> value)
throws PaintException;

/**
* Adds a string type variable.
*

+ 62
- 65
src/com/vaadin/terminal/gwt/client/ApplicationConnection.java Visa fil

@@ -10,20 +10,17 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
@@ -75,7 +72,7 @@ public class ApplicationConnection {

private static Console console;

private final Vector<String> pendingVariables = new Vector<String>();
private final ArrayList<String> pendingVariables = new ArrayList<String>();

private final ComponentDetailMap idToPaintableDetail = ComponentDetailMap
.create();
@@ -99,7 +96,7 @@ public class ApplicationConnection {
private final ApplicationConfiguration configuration;

/** List of pending variable change bursts that must be submitted in order */
private final Vector<Vector<String>> pendingVariableBursts = new Vector<Vector<String>>();
private final ArrayList<ArrayList<String>> pendingVariableBursts = new ArrayList<ArrayList<String>>();

/** Timer for automatic refirect to SessionExpiredURL */
private Timer redirectTimer;
@@ -514,11 +511,11 @@ public class ApplicationConnection {
private void checkForPendingVariableBursts() {
cleanVariableBurst(pendingVariables);
if (pendingVariableBursts.size() > 0) {
for (Iterator<Vector<String>> iterator = pendingVariableBursts
for (Iterator<ArrayList<String>> iterator = pendingVariableBursts
.iterator(); iterator.hasNext();) {
cleanVariableBurst(iterator.next());
}
Vector<String> nextBurst = pendingVariableBursts.firstElement();
ArrayList<String> nextBurst = pendingVariableBursts.get(0);
pendingVariableBursts.remove(0);
buildAndSendVariableBurst(nextBurst, false);
}
@@ -530,7 +527,7 @@ public class ApplicationConnection {
*
* @param variableBurst
*/
private void cleanVariableBurst(Vector<String> variableBurst) {
private void cleanVariableBurst(ArrayList<String> variableBurst) {
for (int i = 1; i < variableBurst.size(); i += 2) {
String id = variableBurst.get(i);
id = id.substring(0, id.indexOf(VAR_FIELD_SEPARATOR));
@@ -591,14 +588,19 @@ public class ApplicationConnection {
}
}

private static native ValueMap parseJSONResponse(String jsonText)
/*-{
return $wnd.eval('(' + jsonText + ')');
}-*/;

private void handleReceivedJSONMessage(Response response) {
final Date start = new Date();
String jsonText = response.getText();
// for(;;);[realjson]
jsonText = jsonText.substring(9, jsonText.length() - 1);
JSONValue json;
ValueMap json;
try {
json = JSONParser.parse(jsonText);
json = parseJSONResponse(jsonText);
} catch (final com.google.gwt.json.client.JSONException e) {
endRequest();
showCommunicationError(e.getMessage() + " - Original JSON-text:");
@@ -606,38 +608,33 @@ public class ApplicationConnection {
return;
}
// Handle redirect
final JSONObject redirect = (JSONObject) ((JSONObject) json)
.get("redirect");
if (redirect != null) {
final JSONString url = (JSONString) redirect.get("url");
if (url != null) {
console.log("redirecting to " + url.stringValue());
redirect(url.stringValue());
return;
}
if (json.containsKey("redirect")) {
String url = json.getValueMap("redirect").getString("url");
console.log("redirecting to " + url);
redirect(url);
return;
}

// Store resources
final JSONObject resources = (JSONObject) ((JSONObject) json)
.get("resources");
for (final Iterator<String> i = resources.keySet().iterator(); i
.hasNext();) {
final String key = i.next();
resourcesMap.put(key, ((JSONString) resources.get(key))
.stringValue());
if (json.containsKey("resources")) {
ValueMap resources = json.getValueMap("resources");
JsArrayString keyArray = resources.getKeyArray();
int l = keyArray.length();
for (int i = 0; i < l; i++) {
String key = keyArray.get(i);
resourcesMap.put(key, resources.getAsString(key));
}
}

// Store locale data
if (((JSONObject) json).containsKey("locales")) {
final JSONArray l = (JSONArray) ((JSONObject) json).get("locales");
for (int i = 0; i < l.size(); i++) {
LocaleService.addLocale((JSONObject) l.get(i));
}
if (json.containsKey("locales")) {
// Store locale data
JsArray<ValueMap> valueMapArray = json
.getJSValueMapArray("locales");
LocaleService.addLocales(valueMapArray);
}

JSONObject meta = null;
if (((JSONObject) json).containsKey("meta")) {
meta = ((JSONObject) json).get("meta").isObject();
ValueMap meta = null;
if (json.containsKey("meta")) {
meta = json.getValueMap("meta");
if (meta.containsKey("repaintAll")) {
view.clear();
idToPaintableDetail.clear();
@@ -648,33 +645,33 @@ public class ApplicationConnection {
}
}
if (meta.containsKey("timedRedirect")) {
final JSONObject timedRedirect = meta.get("timedRedirect")
.isObject();
final ValueMap timedRedirect = meta
.getValueMap("timedRedirect");
redirectTimer = new Timer() {
@Override
public void run() {
redirect(timedRedirect.get("url").isString()
.stringValue());
redirect(timedRedirect.getString("url"));
}
};
sessionExpirationInterval = Integer.parseInt(timedRedirect.get(
"interval").toString());
sessionExpirationInterval = timedRedirect.getInt("interval");
}
}

if (redirectTimer != null) {
redirectTimer.schedule(1000 * sessionExpirationInterval);
}

// Process changes
final JSONArray changes = (JSONArray) ((JSONObject) json)
.get("changes");
JsArray<ValueMap> changes = json.getJSValueMapArray("changes");

Vector<Paintable> updatedWidgets = new Vector<Paintable>();
ArrayList<Paintable> updatedWidgets = new ArrayList<Paintable>();
relativeSizeChanges.clear();
componentCaptionSizeChanges.clear();

for (int i = 0; i < changes.size(); i++) {
int length = changes.length();
for (int i = 0; i < length; i++) {
try {
final UIDL change = new UIDL((JSONArray) changes.get(i));
final UIDL change = changes.get(i).cast();
try {
console.dirUIDL(change);
} catch (final Exception e) {
@@ -732,20 +729,17 @@ public class ApplicationConnection {

if (meta != null) {
if (meta.containsKey("appError")) {
JSONObject error = meta.get("appError").isObject();
JSONValue val = error.get("caption");
ValueMap error = meta.getValueMap("appError");
String html = "";
if (val.isString() != null) {
html += "<h1>" + val.isString().stringValue() + "</h1>";
if (error.containsKey("caption")) {
html += "<h1>" + error.getAsString("caption") + "</h1>";
}
val = error.get("message");
if (val.isString() != null) {
html += "<p>" + val.isString().stringValue() + "</p>";
if (error.containsKey("message")) {
html += "<p>" + error.getAsString("message") + "</p>";
}
val = error.get("url");
String url = null;
if (val.isString() != null) {
url = val.isString().stringValue();
if (error.containsKey("url")) {
url = error.getAsString("url");
}

if (html.length() != 0) {
@@ -760,8 +754,7 @@ public class ApplicationConnection {
applicationRunning = false;
}
if (validatingLayouts) {
getConsole().printLayoutProblems(
meta.get("invalidLayouts").isArray(), this,
getConsole().printLayoutProblems(meta, this,
zeroHeightComponents, zeroWidthComponents);
zeroHeightComponents = null;
zeroWidthComponents = null;
@@ -778,6 +771,10 @@ public class ApplicationConnection {
endRequest();
}

private UIDL getUidl(JSONArray changes, int i) {
return (UIDL) changes.get(i).isArray().getJavaScriptObject();
}

/**
* This method assures that all pending variable changes are sent to server.
* Method uses synchronized xmlhttprequest and does not return before the
@@ -788,7 +785,7 @@ public class ApplicationConnection {
public void sendPendingVariableChangesSync() {
if (applicationRunning) {
pendingVariableBursts.add(pendingVariables);
Vector<String> nextBurst = pendingVariableBursts.firstElement();
ArrayList<String> nextBurst = pendingVariableBursts.get(0);
pendingVariableBursts.remove(0);
buildAndSendVariableBurst(nextBurst, true);
}
@@ -904,7 +901,7 @@ public class ApplicationConnection {
// skip empty queues if there are pending bursts to be sent
if (pendingVariables.size() > 0
|| pendingVariableBursts.size() == 0) {
Vector<String> burst = (Vector<String>) pendingVariables
ArrayList<String> burst = (ArrayList<String>) pendingVariables
.clone();
pendingVariableBursts.add(burst);
pendingVariables.clear();
@@ -927,7 +924,7 @@ public class ApplicationConnection {
* @param forceSync
* Should we use synchronous request?
*/
private void buildAndSendVariableBurst(Vector<String> pendingVariables,
private void buildAndSendVariableBurst(ArrayList<String> pendingVariables,
boolean forceSync) {
final StringBuffer req = new StringBuffer();

@@ -946,7 +943,7 @@ public class ApplicationConnection {
pendingVariables.clear();
// Append all the busts to this synchronous request
if (forceSync && !pendingVariableBursts.isEmpty()) {
pendingVariables = pendingVariableBursts.firstElement();
pendingVariables = pendingVariableBursts.get(0);
pendingVariableBursts.remove(0);
req.append(VAR_BURST_SEPARATOR);
}

+ 1
- 3
src/com/vaadin/terminal/gwt/client/Console.java Visa fil

@@ -6,8 +6,6 @@ package com.vaadin.terminal.gwt.client;

import java.util.Set;

import com.google.gwt.json.client.JSONArray;

public interface Console {

public abstract void log(String msg);
@@ -18,7 +16,7 @@ public interface Console {

public abstract void dirUIDL(UIDL u);

public abstract void printLayoutProblems(JSONArray array,
public abstract void printLayoutProblems(ValueMap meta,
ApplicationConnection applicationConnection,
Set<Paintable> zeroHeightComponents,
Set<Paintable> zeroWidthComponents);

+ 32
- 81
src/com/vaadin/terminal/gwt/client/LocaleService.java Visa fil

@@ -8,11 +8,7 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.core.client.JsArray;
/**
* Date / time etc. localisation service for all widgets. Caches all loaded
@@ -23,15 +19,16 @@ import com.google.gwt.json.client.JSONString;
*/
public class LocaleService {
private static Map cache = new HashMap();
private static Map<String, ValueMap> cache = new HashMap<String, ValueMap>();
private static String defaultLocale;
public static void addLocale(JSONObject json) {
final String key = ((JSONString) json.get("name")).stringValue();
public static void addLocale(ValueMap valueMap) {
final String key = valueMap.getString("name");
if (cache.containsKey(key)) {
cache.remove(key);
}
cache.put(key, json);
cache.put(key, valueMap);
if (cache.size() == 1) {
setDefaultLocale(key);
}
@@ -52,22 +49,8 @@ public class LocaleService {
public static String[] getMonthNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONArray mn = (JSONArray) l.get("mn");
final String[] temp = new String[12];
temp[0] = ((JSONString) mn.get(0)).stringValue();
temp[1] = ((JSONString) mn.get(1)).stringValue();
temp[2] = ((JSONString) mn.get(2)).stringValue();
temp[3] = ((JSONString) mn.get(3)).stringValue();
temp[4] = ((JSONString) mn.get(4)).stringValue();
temp[5] = ((JSONString) mn.get(5)).stringValue();
temp[6] = ((JSONString) mn.get(6)).stringValue();
temp[7] = ((JSONString) mn.get(7)).stringValue();
temp[8] = ((JSONString) mn.get(8)).stringValue();
temp[9] = ((JSONString) mn.get(9)).stringValue();
temp[10] = ((JSONString) mn.get(10)).stringValue();
temp[11] = ((JSONString) mn.get(11)).stringValue();
return temp;
final ValueMap l = cache.get(locale);
return l.getStringArray("mn");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -76,22 +59,8 @@ public class LocaleService {
public static String[] getShortMonthNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONArray smn = (JSONArray) l.get("smn");
final String[] temp = new String[12];
temp[0] = ((JSONString) smn.get(0)).stringValue();
temp[1] = ((JSONString) smn.get(1)).stringValue();
temp[2] = ((JSONString) smn.get(2)).stringValue();
temp[3] = ((JSONString) smn.get(3)).stringValue();
temp[4] = ((JSONString) smn.get(4)).stringValue();
temp[5] = ((JSONString) smn.get(5)).stringValue();
temp[6] = ((JSONString) smn.get(6)).stringValue();
temp[7] = ((JSONString) smn.get(7)).stringValue();
temp[8] = ((JSONString) smn.get(8)).stringValue();
temp[9] = ((JSONString) smn.get(9)).stringValue();
temp[10] = ((JSONString) smn.get(10)).stringValue();
temp[11] = ((JSONString) smn.get(11)).stringValue();
return temp;
final ValueMap l = cache.get(locale);
return l.getStringArray("smn");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -100,17 +69,8 @@ public class LocaleService {
public static String[] getDayNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONArray dn = (JSONArray) l.get("dn");
final String[] temp = new String[7];
temp[0] = ((JSONString) dn.get(0)).stringValue();
temp[1] = ((JSONString) dn.get(1)).stringValue();
temp[2] = ((JSONString) dn.get(2)).stringValue();
temp[3] = ((JSONString) dn.get(3)).stringValue();
temp[4] = ((JSONString) dn.get(4)).stringValue();
temp[5] = ((JSONString) dn.get(5)).stringValue();
temp[6] = ((JSONString) dn.get(6)).stringValue();
return temp;
final ValueMap l = cache.get(locale);
return l.getStringArray("dn");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -119,17 +79,8 @@ public class LocaleService {
public static String[] getShortDayNames(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONArray sdn = (JSONArray) l.get("sdn");
final String[] temp = new String[7];
temp[0] = ((JSONString) sdn.get(0)).stringValue();
temp[1] = ((JSONString) sdn.get(1)).stringValue();
temp[2] = ((JSONString) sdn.get(2)).stringValue();
temp[3] = ((JSONString) sdn.get(3)).stringValue();
temp[4] = ((JSONString) sdn.get(4)).stringValue();
temp[5] = ((JSONString) sdn.get(5)).stringValue();
temp[6] = ((JSONString) sdn.get(6)).stringValue();
return temp;
final ValueMap l = cache.get(locale);
return l.getStringArray("sdn");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -138,9 +89,8 @@ public class LocaleService {
public static int getFirstDayOfWeek(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONNumber fdow = (JSONNumber) l.get("fdow");
return (int) fdow.getValue();
final ValueMap l = cache.get(locale);
return l.getInt("fdow");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -149,9 +99,8 @@ public class LocaleService {
public static String getDateFormat(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONString df = (JSONString) l.get("df");
return df.stringValue();
final ValueMap l = cache.get(locale);
return l.getString("df");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -160,9 +109,8 @@ public class LocaleService {
public static boolean isTwelveHourClock(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONBoolean thc = (JSONBoolean) l.get("thc");
return thc.booleanValue();
final ValueMap l = cache.get(locale);
return l.getBoolean("thc");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -171,9 +119,8 @@ public class LocaleService {
public static String getClockDelimiter(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONString hmd = (JSONString) l.get("hmd");
return hmd.stringValue();
final ValueMap l = cache.get(locale);
return l.getString("hmd");
} else {
throw new LocaleNotLoadedException(locale);
}
@@ -182,16 +129,20 @@ public class LocaleService {
public static String[] getAmPmStrings(String locale)
throws LocaleNotLoadedException {
if (cache.containsKey(locale)) {
final JSONObject l = (JSONObject) cache.get(locale);
final JSONArray ampm = (JSONArray) l.get("ampm");
final String[] temp = new String[2];
temp[0] = ((JSONString) ampm.get(0)).stringValue();
temp[1] = ((JSONString) ampm.get(1)).stringValue();
return temp;
final ValueMap l = cache.get(locale);
return l.getStringArray("ampm");
} else {
throw new LocaleNotLoadedException(locale);
}
}
public static void addLocales(JsArray<ValueMap> valueMapArray) {
for (int i = 0; i < valueMapArray.length(); i++) {
addLocale(valueMapArray.get(i));
}
}
}

+ 1
- 3
src/com/vaadin/terminal/gwt/client/NullConsole.java Visa fil

@@ -6,8 +6,6 @@ package com.vaadin.terminal.gwt.client;

import java.util.Set;

import com.google.gwt.json.client.JSONArray;

/**
* Client side console implementation for non-debug mode that discards all
* messages.
@@ -27,7 +25,7 @@ public class NullConsole implements Console {
public void printObject(Object msg) {
}

public void printLayoutProblems(JSONArray array,
public void printLayoutProblems(ValueMap meta,
ApplicationConnection applicationConnection,
Set<Paintable> zeroHeightComponents,
Set<Paintable> zeroWidthComponents) {

+ 155
- 346
src/com/vaadin/terminal/gwt/client/UIDL.java Visa fil

@@ -8,166 +8,129 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

public class UIDL {

JSONArray json;

public UIDL(JSONArray json) {
this.json = json;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayString;

public final class UIDL extends JavaScriptObject {

protected UIDL() {
}

public String getId() {
final JSONValue val = ((JSONObject) json.get(1)).get("id");
if (val == null) {
return null;
}
return ((JSONString) val).stringValue();
return getStringAttribute("id");
}

public String getTag() {
return ((JSONString) json.get(0)).stringValue();
}
public native String getTag()
/*-{
return this[0];
}-*/;

private native ValueMap attr()
/*-{
return this[1];
}-*/;

private native ValueMap var()
/*-{
return this[1]["v"];
}-*/;

private native boolean hasVariables()
/*-{
return Boolean(this[1]["v"]);
}-*/;

public String getStringAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return null;
}
return ((JSONString) val).stringValue();
return attr().getString(name);
}

public Set<String> getAttributeNames() {
final HashSet<String> attrs = new HashSet<String>(((JSONObject) json
.get(1)).keySet());
attrs.remove("v");
return attrs;
Set<String> keySet = attr().getKeySet();
keySet.remove("v");
return keySet;
}

public int getIntAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return 0;
public Set<String> getVariableNames() {
if (!hasVariables()) {
return new HashSet<String>();
} else {
Set<String> keySet = var().getKeySet();
return keySet;
}
final double num = val.isNumber().doubleValue();
return (int) num;
}

public int getIntAttribute(String name) {
return attr().getInt(name);
}

public long getLongAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return 0;
}
final double num = val.isNumber().doubleValue();
return (long) num;
return (long) attr().getRawNumber(name);
}

public float getFloatAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return 0;
}
final double num = val.isNumber().doubleValue();
return (float) num;
return (float) attr().getRawNumber(name);
}

public double getDoubleAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return 0;
}
final double num = val.isNumber().doubleValue();
return num;
return attr().getRawNumber(name);
}

public boolean getBooleanAttribute(String name) {
final JSONValue val = ((JSONObject) json.get(1)).get(name);
if (val == null) {
return false;
}
return val.isBoolean().booleanValue();
return attr().getBoolean(name);
}

public String[] getStringArrayAttribute(String name) {
final JSONArray a = (JSONArray) ((JSONObject) json.get(1)).get(name);
final String[] s = new String[a.size()];
for (int i = 0; i < a.size(); i++) {
s[i] = ((JSONString) a.get(i)).stringValue();
}
return s;
public ValueMap getMapAttribute(String name) {
return attr().getValueMap(name);
}

public int[] getIntArrayAttribute(String name) {
final JSONArray a = (JSONArray) ((JSONObject) json.get(1)).get(name);
final int[] s = new int[a.size()];
for (int i = 0; i < a.size(); i++) {
s[i] = Integer.parseInt(((JSONString) a.get(i)).stringValue());
}
return s;
public String[] getStringArrayAttribute(String name) {
return attr().getStringArray(name);
}

public HashSet<String> getStringArrayAttributeAsSet(String string) {
final JSONArray a = getArrayVariable(string);
final HashSet<String> s = new HashSet<String>();
for (int i = 0; i < a.size(); i++) {
s.add(((JSONString) a.get(i)).stringValue());
}
return s;
public int[] getIntArrayAttribute(final String name) {
return attr().getIntArray(name);
}

/**
* Get attributes value as string whateever the type is
* Get attributes value as string whatever the type is
*
* @param name
* @return string presentation of attribute
*/
private String getAttribute(String name) {
return json.get(1).isObject().get(name).toString();
}

public boolean hasAttribute(String name) {
return ((JSONObject) json.get(1)).get(name) != null;
}
native String getAttribute(String name)
/*-{
return '' + this[1][name];
}-*/;

public UIDL getChildUIDL(int i) {
native String getVariable(String name)
/*-{
return '' + this[1]['v'][name];
}-*/;

final JSONValue c = json.get(i + 2);
if (c == null) {
return null;
}
if (c.isArray() != null) {
return new UIDL(c.isArray());
}
throw new IllegalStateException("Child node " + i
+ " is not of type UIDL");
public boolean hasAttribute(final String name) {
return attr().containsKey(name);
}

public String getChildString(int i) {
public native UIDL getChildUIDL(int i)
/*-{
return this[i + 2];
}-*/;

final JSONValue c = json.get(i + 2);
if (c.isString() != null) {
return ((JSONString) c).stringValue();
}
throw new IllegalStateException("Child node " + i
+ " is not of type String");
}
public native String getChildString(int i)
/*-{
return this[i + 2];
}-*/;

private native XML getChildXML(int index)
/*-{
return this[index + 2];
}-*/;

public Iterator<Object> getChildIterator() {

return new Iterator<Object>() {

int index = 2;
int index = -1;

public void remove() {
throw new UnsupportedOperationException();
@@ -175,296 +138,142 @@ public class UIDL {

public Object next() {

if (json.size() > index) {
final JSONValue c = json.get(index++);
if (c.isString() != null) {
return c.isString().stringValue();
} else if (c.isArray() != null) {
return new UIDL(c.isArray());
} else if (c.isObject() != null) {
return new XML(c.isObject());
} else {
throw new IllegalStateException("Illegal child " + c
+ " in tag " + getTag() + " at index " + index);
if (hasNext()) {
int typeOfChild = typeOfChild(index++);
switch (typeOfChild) {
case CHILD_TYPE_UIDL:
UIDL childUIDL = getChildUIDL(index);
return childUIDL;
case CHILD_TYPE_STRING:
return getChildString(index);
case CHILD_TYPE_XML:
return getChildXML(index);
default:
throw new IllegalStateException(
"Illegal child in tag " + getTag()
+ " at index " + index);
}
}
return null;
}

public boolean hasNext() {
return json.size() > index;
int count = getChildCount();
return count > index + 1;
}

};
}

public int getNumberOfChildren() {
return json.size() - 2;
}
private static final int CHILD_TYPE_STRING = 0;
private static final int CHILD_TYPE_UIDL = 1;
private static final int CHILD_TYPE_XML = 2;

@Override
public String toString() {
String s = "<" + getTag();

Set<String> attributeNames = getAttributeNames();
for (String name : attributeNames) {
s += " " + name + "=";
final JSONValue v = ((JSONObject) json.get(1)).get(name);
if (v.isString() != null) {
s += v;
private native int typeOfChild(int index)
/*-{
var t = typeof this[index + 2];
if(t == "object") {
if(typeof(t.length) == "number") {
return 1;
} else {
s += "\"" + v + "\"";
return 2;
}
} else if (t == "string") {
return 0;
}
return -1;
}-*/;

s += ">\n";

final Iterator<Object> i = getChildIterator();
while (i.hasNext()) {
final Object c = i.next();
s += c.toString();
}

s += "</" + getTag() + ">\n";

return s;
}

/**
*
* @return
*
* @deprecated
*/
@Deprecated
public String getChildrenAsXML() {
String s = "";
final Iterator<Object> i = getChildIterator();
while (i.hasNext()) {
final Object c = i.next();
s += c.toString();
}
return s;
}

public VUIDLBrowser print_r() {
return new VUIDLBrowser();
}

private class VUIDLBrowser extends Tree {
public VUIDLBrowser() {

DOM.setStyleAttribute(getElement(), "position", "");

final TreeItem root = new TreeItem(getTag());
addItem(root);
root.addItem("");
addOpenHandler(new OpenHandler<TreeItem>() {
boolean isLoaded;

public void onOpen(OpenEvent<TreeItem> event) {
TreeItem item = event.getTarget();
if (item == root && !isLoaded) {
removeItem(root);
addItem(dir());
final Iterator<TreeItem> it = treeItemIterator();
while (it.hasNext()) {
it.next().setState(true);
}
isLoaded = true;
}
}
});
}

@Override
protected boolean isKeyboardNavigationEnabled(TreeItem currentItem) {
return false;
}

}

public TreeItem dir() {

String nodeName = getTag();
Set<String> attributeNames = getAttributeNames();
for (String name : attributeNames) {
final String value = getAttribute(name);
nodeName += " " + name + "=" + value;
}
final TreeItem item = new TreeItem(nodeName);

try {
TreeItem tmp = null;
Set<String> keySet = getVariableHash().keySet();
for (String name : keySet) {
String value = "";
try {
value = getStringVariable(name);
} catch (final Exception e) {
try {
final JSONArray a = getArrayVariable(name);
value = a.toString();
} catch (final Exception e2) {
try {
final int intVal = getIntVariable(name);
value = String.valueOf(intVal);
} catch (final Exception e3) {
value = "unknown";
}
}
}
if (tmp == null) {
tmp = new TreeItem("variables");
}
tmp.addItem(name + "=" + value);
}
if (tmp != null) {
item.addItem(tmp);
}
} catch (final Exception e) {
// Ignored, no variables
}

final Iterator<Object> i = getChildIterator();
while (i.hasNext()) {
final Object child = i.next();
try {
final UIDL c = (UIDL) child;
item.addItem(c.dir());

} catch (final Exception e) {
item.addItem(child.toString());
}
}
return item;
}

private JSONObject getVariableHash() {
final JSONObject v = (JSONObject) ((JSONObject) json.get(1)).get("v");
if (v == null) {
throw new IllegalArgumentException("No variables defined in tag.");
}
return v;
return toString();
}

public boolean hasVariable(String name) {
final JSONObject variables = (JSONObject) ((JSONObject) json.get(1))
.get("v");
if (variables == null) {
return false;
}
return variables.keySet().contains(name);
return var().containsKey(name);
}

public String getStringVariable(String name) {
final JSONString t = (JSONString) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return t.stringValue();
return var().getString(name);
}

public int getIntVariable(String name) {
final JSONNumber t = (JSONNumber) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return (int) t.doubleValue();
return var().getInt(name);
}

public long getLongVariable(String name) {
final JSONNumber t = (JSONNumber) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return (long) t.doubleValue();
return (long) var().getRawNumber(name);
}

public float getFloatVariable(String name) {
final JSONNumber t = (JSONNumber) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return (float) t.doubleValue();
return (float) var().getRawNumber(name);
}

public double getDoubleVariable(String name) {
final JSONNumber t = (JSONNumber) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return t.doubleValue();
return var().getRawNumber(name);
}

public boolean getBooleanVariable(String name) {
final JSONBoolean t = (JSONBoolean) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return t.booleanValue();
}

private JSONArray getArrayVariable(String name) {
final JSONArray t = (JSONArray) getVariableHash().get(name);
if (t == null) {
throw new IllegalArgumentException("No such variable: " + name);
}
return t;
return var().getBoolean(name);
}

public String[] getStringArrayVariable(String name) {
final JSONArray a = getArrayVariable(name);
final String[] s = new String[a.size()];
for (int i = 0; i < a.size(); i++) {
s[i] = ((JSONString) a.get(i)).stringValue();
}
return s;
return var().getStringArray(name);
}

public Set<String> getStringArrayVariableAsSet(String name) {
final JSONArray a = getArrayVariable(name);
public Set<String> getStringArrayVariableAsSet(final String name) {
final HashSet<String> s = new HashSet<String>();
for (int i = 0; i < a.size(); i++) {
s.add(((JSONString) a.get(i)).stringValue());
JsArrayString a = var().getJSStringArray(name);
for (int i = 0; i < a.length(); i++) {
s.add(a.get(i));
}
return s;
}

public int[] getIntArrayVariable(String name) {
final JSONArray a = getArrayVariable(name);
final int[] s = new int[a.size()];
for (int i = 0; i < a.size(); i++) {
final JSONValue v = a.get(i);
s[i] = v.isNumber() != null ? (int) v.isNumber().doubleValue()
: Integer.parseInt(v.toString());
}
return s;
return var().getIntArray(name);
}

public class XML {
JSONObject x;

private XML(JSONObject x) {
this.x = x;
public final static class XML extends JavaScriptObject {
protected XML() {
}

public String getXMLAsString() {
final StringBuffer sb = new StringBuffer();
Set<String> keySet = x.keySet();
for (String tag : keySet) {
sb.append("<");
sb.append(tag);
sb.append(">");
sb.append(x.get(tag).isString().stringValue());
sb.append("</");
sb.append(tag);
sb.append(">");
public native String getXMLAsString()
/*-{
var buf = new Array();
var self = this;
for(j in self) {
buf.push("<");
buf.push(j);
buf.push(">");
buf.push(self[j]);
buf.push("</");
buf.push("tag");
buf.push(">");
}
return sb.toString();
}
return buf.join();
}-*/;
}

public int getChildCount() {
return json.size() - 2;
}
public native int getChildCount()
/*-{
return this.length - 2;
}-*/;

public UIDL getErrors() {
final JSONArray a = (JSONArray) ((JSONObject) json.get(1)).get("error");
return new UIDL(a);
}
public native UIDL getErrors()
/*-{
return this[1]['error'];
}-*/;

native boolean isMapAttribute(String name)
/*-{
return typeof this[1][name] == "object";
}-*/;

}

+ 3
- 7
src/com/vaadin/terminal/gwt/client/Util.java Visa fil

@@ -631,16 +631,12 @@ public class Util {
public static native int getRequiredWidth(
com.google.gwt.dom.client.Element element)
/*-{
var width;
if (element == null) {
width = 0;
} else if (element.getBoundingClientRect != null) {
if (element.getBoundingClientRect) {
var rect = element.getBoundingClientRect();
width = Math.ceil(rect.right - rect.left);
return Math.ceil(rect.right - rect.left);
} else {
width = element.offsetWidth;
return element.offsetWidth;
}
return width;
}-*/;

public static native int getRequiredHeight(

+ 35
- 24
src/com/vaadin/terminal/gwt/client/VDebugConsole.java Visa fil

@@ -7,9 +7,7 @@ package com.vaadin.terminal.gwt.client;
import java.util.List;
import java.util.Set;

import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
@@ -331,10 +329,25 @@ public final class VDebugConsole extends VOverlay implements Console {
* .terminal.gwt.client.UIDL)
*/
public void dirUIDL(UIDL u) {
panel.add(u.print_r());
consoleLog(u.getChildrenAsXML());
if (panel.isAttached()) {
panel.add(new VUIDLBrowser(u));
}
consoleDir(u);
// consoleLog(u.getChildrenAsXML());
}

private static native void consoleDir(UIDL u)
/*-{
if($wnd.console && $wnd.console.log) {
if($wnd.console.dir) {
$wnd.console.dir(u);
} else {
$wnd.console.log(u);
}
}
}-*/;

private static native void consoleLog(String msg)
/*-{
if($wnd.console && $wnd.console.log) {
@@ -352,10 +365,12 @@ public final class VDebugConsole extends VOverlay implements Console {
}
}-*/;

public void printLayoutProblems(JSONArray array, ApplicationConnection ac,
public void printLayoutProblems(ValueMap meta, ApplicationConnection ac,
Set<Paintable> zeroHeightComponents,
Set<Paintable> zeroWidthComponents) {
int size = array.size();
JsArray<ValueMap> valueMapArray = meta
.getJSValueMapArray("invalidLayouts");
int size = valueMapArray.length();
panel.add(new HTML("<div>************************</di>"
+ "<h4>Layouts analyzed on server, total top level problems: "
+ size + " </h4>"));
@@ -367,8 +382,7 @@ public final class VDebugConsole extends VOverlay implements Console {

TreeItem root = new TreeItem("Root problems");
for (int i = 0; i < size; i++) {
JSONObject error = array.get(i).isObject();
printLayoutError(error, root, ac);
printLayoutError(valueMapArray.get(i), root, ac);
}
panel.add(tree);
tree.addItem(root);
@@ -418,22 +432,22 @@ public final class VDebugConsole extends VOverlay implements Console {
}
}

private void printLayoutError(JSONObject error, TreeItem parent,
private void printLayoutError(ValueMap valueMap, TreeItem parent,
final ApplicationConnection ac) {
final String pid = error.get("id").isString().stringValue();
final String pid = valueMap.getString("id");
final Paintable paintable = ac.getPaintable(pid);

TreeItem errorNode = new TreeItem();
VerticalPanel errorDetails = new VerticalPanel();
errorDetails.add(new Label(Util.getSimpleName(paintable) + " id: "
+ pid));
if (error.containsKey("heightMsg")) {
if (valueMap.containsKey("heightMsg")) {
errorDetails.add(new Label("Height problem: "
+ error.get("heightMsg")));
+ valueMap.getString("heightMsg")));
}
if (error.containsKey("widthMsg")) {
if (valueMap.containsKey("widthMsg")) {
errorDetails.add(new Label("Width problem: "
+ error.get("widthMsg")));
+ valueMap.getString("widthMsg")));
}
final CheckBox emphasisInUi = new CheckBox("Emphasis component in UI");
emphasisInUi.addClickListener(new ClickListener() {
@@ -447,18 +461,15 @@ public final class VDebugConsole extends VOverlay implements Console {
});
errorDetails.add(emphasisInUi);
errorNode.setWidget(errorDetails);
if (error.containsKey("subErrors")) {
if (valueMap.containsKey("subErrors")) {
HTML l = new HTML(
"<em>Expand this node to show problems that may be dependent on this problem.</em>");
errorDetails.add(l);
JSONArray array = error.get("subErrors").isArray();
for (int i = 0; i < array.size(); i++) {
JSONValue value = array.get(i);
if (value != null && value.isObject() != null) {
printLayoutError(value.isObject(), errorNode, ac);
} else {
System.out.print(value);
}
JsArray<ValueMap> suberrors = valueMap
.getJSValueMapArray("subErrors");
for (int i = 0; i < suberrors.length(); i++) {
ValueMap value = suberrors.get(i);
printLayoutError(value, errorNode, ac);
}

}

+ 134
- 0
src/com/vaadin/terminal/gwt/client/VUIDLBrowser.java Visa fil

@@ -0,0 +1,134 @@
/**
*
*/
package com.vaadin.terminal.gwt.client;

import java.util.Iterator;
import java.util.Set;

import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.event.logical.shared.OpenEvent;
import com.google.gwt.event.logical.shared.OpenHandler;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

public class VUIDLBrowser extends Tree {
/**
*
*/
private final UIDL uidl;

public VUIDLBrowser(final UIDL uidl) {

this.uidl = uidl;
DOM.setStyleAttribute(getElement(), "position", "");

final UIDLItem root = new UIDLItem(this.uidl);
addItem(root);
addOpenHandler(new OpenHandler<TreeItem>() {
public void onOpen(OpenEvent<TreeItem> event) {
TreeItem item = event.getTarget();
if (item.getChildCount() == 1
&& item.getChild(0).getText().equals("LOADING")) {
((UIDLItem) item).dir();
}
}
});
}

@Override
protected boolean isKeyboardNavigationEnabled(TreeItem currentItem) {
return false;
}

class UIDLItem extends TreeItem {

private UIDL uidl;

UIDLItem(UIDL uidl) {
this.uidl = uidl;
try {
setText(uidl.getTag());
addItem("LOADING");
} catch (Exception e) {
setText(uidl.toString());
}
}

public void dir() {
TreeItem temp = getChild(0);
removeItem(temp);

String nodeName = uidl.getTag();
Set<String> attributeNames = uidl.getAttributeNames();
for (String name : attributeNames) {
if (uidl.isMapAttribute(name)) {
try {
ValueMap map = uidl.getMapAttribute(name);
JsArrayString keyArray = map.getKeyArray();
nodeName += " " + name + "=" + "{";
for (int i = 0; i < keyArray.length(); i++) {
nodeName += keyArray.get(i) + ":"
+ map.getAsString(keyArray.get(i)) + ",";
}
nodeName += "}";
} catch (Exception e) {

}
} else {
final String value = uidl.getAttribute(name);
nodeName += " " + name + "=" + value;
}
}
setText(nodeName);

try {
TreeItem tmp = null;
Set<String> variableNames = uidl.getVariableNames();
for (String name : variableNames) {
String value = "";
try {
value = uidl.getVariable(name);
} catch (final Exception e) {
try {
String[] stringArrayAttribute = uidl
.getStringArrayAttribute(name);
value = stringArrayAttribute.toString();
} catch (final Exception e2) {
try {
final int intVal = uidl.getIntVariable(name);
value = String.valueOf(intVal);
} catch (final Exception e3) {
value = "unknown";
}
}
}
if (tmp == null) {
tmp = new TreeItem("variables");
}
tmp.addItem(name + "=" + value);
}
if (tmp != null) {
addItem(tmp);
}
} catch (final Exception e) {
// Ignored, no variables
}

final Iterator<Object> i = uidl.getChildIterator();
while (i.hasNext()) {
final Object child = i.next();
try {
final UIDL c = (UIDL) child;
final TreeItem childItem = new UIDLItem(c);
addItem(childItem);

} catch (final Exception e) {
addItem(child.toString());
}
}
}
}

}

+ 99
- 0
src/com/vaadin/terminal/gwt/client/ValueMap.java Visa fil

@@ -0,0 +1,99 @@
/**
*
*/
package com.vaadin.terminal.gwt.client;

import java.util.HashSet;
import java.util.Set;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArray;
import com.google.gwt.core.client.JsArrayString;

public final class ValueMap extends JavaScriptObject {
protected ValueMap() {
}

public native double getRawNumber(final String name)
/*-{
return this[name];
}-*/;

public native int getInt(final String name)
/*-{
return this[name];
}-*/;

public native boolean getBoolean(final String name)
/*-{
return Boolean(this[name]);
}-*/;

public native String getString(String name)
/*-{
return this[name];
}-*/;

public native JsArrayString getKeyArray()
/*-{
var a = new Array();
var attr = this;
for(var j in attr) {
a.push(j);
}
return a;
}-*/;

public Set<String> getKeySet() {
final HashSet<String> attrs = new HashSet<String>();
JsArrayString attributeNamesArray = getKeyArray();
for (int i = 0; i < attributeNamesArray.length(); i++) {
attrs.add(attributeNamesArray.get(i));
}
return attrs;
}

native JsArrayString getJSStringArray(String name)
/*-{
return this[name];
}-*/;

native JsArray<ValueMap> getJSValueMapArray(String name)
/*-{
return this[name];
}-*/;

public String[] getStringArray(final String name) {
JsArrayString stringArrayAttribute = getJSStringArray(name);
final String[] s = new String[stringArrayAttribute.length()];
for (int i = 0; i < stringArrayAttribute.length(); i++) {
s[i] = stringArrayAttribute.get(i);
}
return s;
}

public int[] getIntArray(final String name) {
JsArrayString stringArrayAttribute = getJSStringArray(name);
final int[] s = new int[stringArrayAttribute.length()];
for (int i = 0; i < stringArrayAttribute.length(); i++) {
s[i] = Integer.parseInt(stringArrayAttribute.get(i));
}
return s;
}

public native boolean containsKey(final String name)
/*-{
return name in this;
}-*/;

public native ValueMap getValueMap(String name)
/*-{
return this[name];
}-*/;

native String getAsString(String name)
/*-{
return '' + this[name];
}-*/;

}

+ 2
- 2
src/com/vaadin/terminal/gwt/client/ui/VListSelect.java Visa fil

@@ -4,8 +4,8 @@

package com.vaadin.terminal.gwt.client.ui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.ListBox;
@@ -61,7 +61,7 @@ public class VListSelect extends VOptionGroupBase {

@Override
protected Object[] getSelectedItems() {
final Vector selectedItemKeys = new Vector();
final ArrayList selectedItemKeys = new ArrayList();
for (int i = 0; i < select.getItemCount(); i++) {
if (select.isItemSelected(i)) {
selectedItemKeys.add(select.getValue(i));

+ 2
- 2
src/com/vaadin/terminal/gwt/client/ui/VNativeSelect.java Visa fil

@@ -4,8 +4,8 @@

package com.vaadin.terminal.gwt.client.ui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.BrowserInfo;
@@ -62,7 +62,7 @@ public class VNativeSelect extends VOptionGroupBase implements Field {

@Override
protected Object[] getSelectedItems() {
final Vector selectedItemKeys = new Vector();
final ArrayList selectedItemKeys = new ArrayList();
for (int i = 0; i < select.getItemCount(); i++) {
if (select.isItemSelected(i)) {
selectedItemKeys.add(select.getValue(i));

+ 51
- 9
src/com/vaadin/terminal/gwt/client/ui/VOrderedLayout.java Visa fil

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import com.google.gwt.core.client.JsArrayString;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
@@ -11,6 +12,7 @@ import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderSpace;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ValueMap;
import com.vaadin.terminal.gwt.client.RenderInformation.FloatSize;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.ui.layout.CellBasedLayout;
@@ -36,6 +38,14 @@ public class VOrderedLayout extends CellBasedLayout {
private boolean sizeHasChangedDuringRendering = false;
private ValueMap expandRatios;
private double expandRatioSum;
private double defaultExpandRatio;
private ValueMap alignments;
public VOrderedLayout() {
this(CLASSNAME, ORIENTATION_VERTICAL);
allowOrientationUpdate = true;
@@ -278,9 +288,12 @@ public class VOrderedLayout extends CellBasedLayout {
}
if (remaining > 0) {
// Some left-over pixels due to rounding errors
// Add one pixel to each container until there are no pixels left
// FIXME extra pixels should be divided among expanded widgets if
// such a widgets exists
Iterator<Widget> widgetIterator = iterator();
while (widgetIterator.hasNext() && remaining-- > 0) {
@@ -836,28 +849,57 @@ public class VOrderedLayout extends CellBasedLayout {
ArrayList<Widget> renderedWidgets) {
/*
* UIDL contains component alignments as a comma separated list.
*
* See com.vaadin.terminal.gwt.client.ui.AlignmentInfo.java for possible
* values.
*/
final int[] alignments = uidl.getIntArrayAttribute("alignments");
alignments = uidl.getMapAttribute("alignments");
/*
* UIDL contains normalized expand ratios as a comma separated list.
* UIDL contains a map of paintable ids to expand ratios
*/
final int[] expandRatios = uidl.getIntArrayAttribute("expandRatios");
expandRatios = uidl.getMapAttribute("expandRatios");
expandRatioSum = -1.0;
for (int i = 0; i < renderedWidgets.size(); i++) {
Widget widget = renderedWidgets.get(i);
String pid = client.getPid(widget.getElement());
ChildComponentContainer container = getComponentContainer(widget);
// Calculate alignment info
container.setAlignment(new AlignmentInfo(alignments[i]));
container.setAlignment(getAlignment(pid));
// Update expand ratio
container.setExpandRatio(expandRatios[i]);
container.setNormalizedExpandRatio(getExpandRatio(pid));
}
}
private AlignmentInfo getAlignment(String pid) {
if (alignments.containsKey(pid)) {
return new AlignmentInfo(alignments.getInt(pid));
} else {
return AlignmentInfo.TOP_LEFT;
}
}
private double getExpandRatio(String pid) {
if (expandRatioSum < 0) {
expandRatioSum = 0;
JsArrayString keyArray = expandRatios.getKeyArray();
int length = keyArray.length();
for (int i = 0; i < length; i++) {
expandRatioSum += expandRatios.getRawNumber(keyArray.get(i));
}
if (expandRatioSum == 0) {
// by default split equally among components
defaultExpandRatio = 1.0 / widgetToComponentContainer.size();
} else {
defaultExpandRatio = 0;
}
}
if (expandRatios.containsKey(pid)) {
return expandRatios.getRawNumber(pid) / expandRatioSum;
} else {
return defaultExpandRatio;
}
}

+ 6
- 8
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java Visa fil

@@ -11,7 +11,6 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NodeList;
@@ -1395,7 +1394,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {

private static final int WRAPPER_WIDTH = 9000;

Vector<Widget> visibleCells = new Vector<Widget>();
ArrayList<Widget> visibleCells = new ArrayList<Widget>();

HashMap<String, HeaderCell> availableCells = new HashMap<String, HeaderCell>();

@@ -1558,8 +1557,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {
// insert to right slot
DOM.insertChild(tr, cell.getElement(), index);
adopt(cell);
visibleCells.insertElementAt(cell, index);

visibleCells.add(index, cell);
} else if (index == visibleCells.size()) {
// simply append
DOM.appendChild(tr, cell.getElement());
@@ -1600,7 +1598,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {
DOM.removeChild(tr, cell);

DOM.insertChild(tr, cell, newIndex);
visibleCells.insertElementAt(hCell, newIndex);
visibleCells.add(newIndex, hCell);
}

public Iterator<Widget> iterator() {
@@ -1790,7 +1788,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {

private int rowHeight = -1;

private final List<Widget> renderedRows = new Vector<Widget>();
private final List<Widget> renderedRows = new ArrayList<Widget>();

/**
* Due some optimizations row height measuring is deferred and initial
@@ -2220,7 +2218,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {
public class VScrollTableRow extends Panel implements ActionOwner,
Container {

Vector<Widget> childWidgets = new Vector<Widget>();
ArrayList<Widget> childWidgets = new ArrayList<Widget>();
private boolean selected = false;
private final int rowKey;
private List<UIDL> pendingComponentPaints;
@@ -2628,7 +2626,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollListener {
oldComponent.removeFromParent();

parentElement.appendChild(newComponent.getElement());
childWidgets.insertElementAt(newComponent, index);
childWidgets.add(index, newComponent);
adopt(newComponent);

}

+ 2
- 2
src/com/vaadin/terminal/gwt/client/ui/VTablePaging.java Visa fil

@@ -4,10 +4,10 @@

package com.vaadin.terminal.gwt.client.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
@@ -50,7 +50,7 @@ public class VTablePaging extends Composite implements Table, Paintable,

private int selectMode = Table.SELECT_MODE_NONE;

private final Vector selectedRowKeys = new Vector();
private final ArrayList selectedRowKeys = new ArrayList();

private int totalRows;


+ 2
- 2
src/com/vaadin/terminal/gwt/client/ui/VTwinColSelect.java Visa fil

@@ -4,8 +4,8 @@
package com.vaadin.terminal.gwt.client.ui;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.FlowPanel;
@@ -111,7 +111,7 @@ public class VTwinColSelect extends VOptionGroupBase {
@Override
protected Object[] getSelectedItems() {
final Vector selectedItemKeys = new Vector();
final ArrayList selectedItemKeys = new ArrayList();
for (int i = 0; i < selections.getItemCount(); i++) {
selectedItemKeys.add(selections.getValue(i));
}

+ 10
- 5
src/com/vaadin/terminal/gwt/client/ui/VUnknownComponent.java Visa fil

@@ -10,16 +10,17 @@ import com.google.gwt.user.client.ui.VerticalPanel;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.VUIDLBrowser;

public class VUnknownComponent extends Composite implements Paintable {

com.google.gwt.user.client.ui.Label caption = new com.google.gwt.user.client.ui.Label();;
Tree uidlTree = new Tree();
Tree uidlTree;
private VerticalPanel panel;

public VUnknownComponent() {
final VerticalPanel panel = new VerticalPanel();
panel = new VerticalPanel();
panel.add(caption);
panel.add(uidlTree);
initWidget(panel);
setStyleName("vaadin-unknown");
caption.setStyleName("vaadin-unknown-caption");
@@ -30,8 +31,12 @@ public class VUnknownComponent extends Composite implements Paintable {
return;
}
setCaption("Client faced an unknown component type. Unrendered UIDL:");
uidlTree.clear();
uidlTree.addItem(uidl.dir());
if (uidlTree != null) {
uidlTree.removeFromParent();
}

uidlTree = new VUIDLBrowser(uidl);
panel.add(uidlTree);
}

public void setCaption(String c) {

+ 3
- 3
src/com/vaadin/terminal/gwt/client/ui/VWindow.java Visa fil

@@ -4,9 +4,9 @@

package com.vaadin.terminal.gwt.client.ui;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import java.util.Vector;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
@@ -41,7 +41,7 @@ public class VWindow extends VOverlay implements Container, ScrollListener {

private static final int MIN_WIDTH = 150;

private static Vector<VWindow> windowOrder = new Vector<VWindow>();
private static ArrayList<VWindow> windowOrder = new ArrayList<VWindow>();

public static final String CLASSNAME = "v-window";

@@ -158,7 +158,7 @@ public class VWindow extends VOverlay implements Container, ScrollListener {
* @return
*/
private boolean isActive() {
return windowOrder.lastElement().equals(this);
return windowOrder.get(windowOrder.size() - 1).equals(this);
}

public void setWindowOrder(int order) {

+ 11
- 5
src/com/vaadin/terminal/gwt/client/ui/layout/ChildComponentContainer.java Visa fil

@@ -40,11 +40,12 @@ public class ChildComponentContainer extends Panel {
private int captionHeight = 0;

/**
*
* Padding added to the container when it is larger than the component.
*/
private Size containerExpansion = new Size(0, 0);

private float expandRatio;
private double expandRatio;

private int containerMarginLeft = 0;
private int containerMarginTop = 0;
@@ -405,7 +406,6 @@ public class ChildComponentContainer extends Panel {

public void setAlignment(AlignmentInfo alignmentInfo) {
alignment = alignmentInfo;

}

public Size getWidgetSize() {
@@ -650,12 +650,18 @@ public class ChildComponentContainer extends Panel {

}

public void setExpandRatio(int expandRatio) {
this.expandRatio = (expandRatio / 1000.0f);
/**
* Sets the normalized expand ratio of this slot. The fraction that this
* slot will use of "excess space".
*
* @param expandRatio
*/
public void setNormalizedExpandRatio(double expandRatio) {
this.expandRatio = expandRatio;
}

public int expand(int orientation, int spaceForExpansion) {
int expansionAmount = (int) ((double) spaceForExpansion * expandRatio);
int expansionAmount = (int) (spaceForExpansion * expandRatio);

if (orientation == CellBasedLayout.ORIENTATION_HORIZONTAL) {
// HORIZONTAL

+ 50
- 9
src/com/vaadin/terminal/gwt/server/JsonPaintTarget.java Visa fil

@@ -9,6 +9,7 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.Vector;
@@ -22,6 +23,7 @@ import com.vaadin.terminal.Paintable;
import com.vaadin.terminal.Resource;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.terminal.VariableOwner;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Component;

/**
@@ -479,6 +481,44 @@ public class JsonPaintTarget implements PaintTarget {

}

public void addAttribute(String name, Map<?, ?> value)
throws PaintException {

StringBuilder sb = new StringBuilder();
sb.append("\"");
sb.append(name);
sb.append("\": ");
sb.append("{");
for (Iterator<?> it = value.keySet().iterator(); it.hasNext();) {
Object key = it.next();
Object mapValue = value.get(key);
sb.append("\"");
if (key instanceof Paintable) {
Paintable paintable = (Paintable) key;
sb.append(getPaintIdentifier(paintable));
} else {
sb.append(escapeJSON(key.toString()));
}
sb.append("\":");
if (mapValue instanceof Float || mapValue instanceof Integer
|| mapValue instanceof Double
|| mapValue instanceof Boolean
|| mapValue instanceof Alignment) {
sb.append(mapValue);
} else {
sb.append("\"");
sb.append(escapeJSON(mapValue.toString()));
sb.append("\"");
}
if (it.hasNext()) {
sb.append(",");
}
}
sb.append("}");

tag.addAttribute(sb.toString());
}

public void addAttribute(String name, Object[] values) {
// In case of null data output nothing:
if ((values == null) || (name == null)) {
@@ -701,8 +741,8 @@ public class JsonPaintTarget implements PaintTarget {
* @throws PaintException
* if the paint operation failed.
*
* @see com.vaadin.terminal.PaintTarget#addXMLSection(String,
* String, String)
* @see com.vaadin.terminal.PaintTarget#addXMLSection(String, String,
* String)
*/
public void addXMLSection(String sectionTagName, String sectionData,
String namespace) throws PaintException {
@@ -766,8 +806,7 @@ public class JsonPaintTarget implements PaintTarget {
/*
* (non-Javadoc)
*
* @see
* com.vaadin.terminal.PaintTarget#startTag(com.vaadin.terminal
* @see com.vaadin.terminal.PaintTarget#startTag(com.vaadin.terminal
* .Paintable, java.lang.String)
*/
public boolean startTag(Paintable paintable, String tagName)
@@ -785,22 +824,24 @@ public class JsonPaintTarget implements PaintTarget {

public void paintReference(Paintable paintable, String referenceName)
throws PaintException {
final String id = getPaintIdentifier(paintable);
addAttribute(referenceName, id);
}

public String getPaintIdentifier(Paintable paintable) throws PaintException {
if (!manager.hasPaintableId(paintable)) {
if (identifiersCreatedDueRefPaint == null) {
identifiersCreatedDueRefPaint = new HashSet<Paintable>();
}
identifiersCreatedDueRefPaint.add(paintable);
}
final String id = manager.getPaintableId(paintable);
addAttribute(referenceName, id);
return manager.getPaintableId(paintable);
}

/*
* (non-Javadoc)
*
* @see
* com.vaadin.terminal.PaintTarget#addCharacterData(java.lang.String
* )
* @see com.vaadin.terminal.PaintTarget#addCharacterData(java.lang.String )
*/
public void addCharacterData(String text) throws PaintException {
if (text != null) {

+ 5
- 49
src/com/vaadin/ui/AbstractOrderedLayout.java Visa fil

@@ -8,7 +8,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Map.Entry;

import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
@@ -133,58 +132,15 @@ public abstract class AbstractOrderedLayout extends AbstractLayout implements
target.addAttribute("spacing", spacing);
}

final String[] alignmentsArray = new String[components.size()];
final Integer[] expandRatioArray = new Integer[components.size()];
float sum = getExpandRatioSum();
boolean equallyDivided = false;
int realSum = 0;
if (sum == 0 && components.size() > 0) {
// no component has been expanded, all components have same expand
// rate
equallyDivided = true;
float equalSize = 1 / (float) components.size();
int myRatio = Math.round(equalSize * 1000);
for (int i = 0; i < expandRatioArray.length; i++) {
expandRatioArray[i] = myRatio;
}
realSum = myRatio * components.size();
}

// Adds all items in all the locations
int index = 0;
for (final Iterator i = components.iterator(); i.hasNext();) {
final Component c = (Component) i.next();
if (c != null) {
// Paint child component UIDL
c.paint(target);
alignmentsArray[index] = String
.valueOf(getComponentAlignment(c).getBitMask());
if (!equallyDivided) {
int myRatio = Math.round((getExpandRatio(c) / sum) * 1000);
expandRatioArray[index] = myRatio;
realSum += myRatio;
}
index++;
}
}

// correct possible rounding error
if (expandRatioArray.length > 0) {
expandRatioArray[0] -= realSum - 1000;
for (Component c : components) {
// Paint child component UIDL
c.paint(target);
}

// Add child component alignment info to layout tag
target.addAttribute("alignments", alignmentsArray);
target.addAttribute("expandRatios", expandRatioArray);
}

private float getExpandRatioSum() {
float sum = 0;
for (Iterator<Entry<Component, Float>> iterator = componentToExpandRatio
.entrySet().iterator(); iterator.hasNext();) {
sum += iterator.next().getValue();
}
return sum;
target.addAttribute("alignments", componentToAlignment);
target.addAttribute("expandRatios", componentToExpandRatio);
}

/* Documented in superclass */

Laddar…
Avbryt
Spara