2011-11-25 8 views
5

Podążam za internationalization chapter. Po zakończeniu czynności w celu przetłumaczenia treści niemiecki, otrzymuję ten błąd przy próbie załadowania strony w przeglądarce:StockWatcher: błędy podczas tłumaczenia zawartości na niemiecki

11:26:27.142 [ERROR] [stockwatcher] Error while executing the JavaScript provider for property 'locale' 
com.google.gwt.core.client.JavaScriptException: (TypeError): Property 'locale' of object is not a function 
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:248) 
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269) 
    at com.google.gwt.dev.shell.ModuleSpacePropertyOracle.computePropertyValue(ModuleSpacePropertyOracle.java:193) 
    at com.google.gwt.dev.shell.ModuleSpacePropertyOracle.getSelectionProperty(ModuleSpacePropertyOracle.java:130) 
    at com.google.gwt.i18n.rebind.LocaleUtils.getInstance(LocaleUtils.java:85) 
    at com.google.gwt.i18n.rebind.LocaleInfoGenerator.generate(LocaleInfoGenerator.java:101) 
    at com.google.gwt.core.ext.GeneratorExtWrapper.generate(GeneratorExtWrapper.java:48) 
    at com.google.gwt.core.ext.GeneratorExtWrapper.generateIncrementally(GeneratorExtWrapper.java:60) 
    at com.google.gwt.dev.javac.StandardGeneratorContext.runGeneratorIncrementally(StandardGeneratorContext.java:647) 
    at com.google.gwt.dev.cfg.RuleGenerateWith.realize(RuleGenerateWith.java:41) 
    at com.google.gwt.dev.shell.StandardRebindOracle$Rebinder.rebind(StandardRebindOracle.java:78) 
    at com.google.gwt.dev.shell.StandardRebindOracle.rebind(StandardRebindOracle.java:268) 
    at com.google.gwt.dev.shell.ShellModuleSpaceHost.rebind(ShellModuleSpaceHost.java:141) 
    at com.google.gwt.dev.shell.ModuleSpace.rebind(ModuleSpace.java:585) 
    at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:455) 
    at com.google.gwt.dev.shell.GWTBridgeImpl.create(GWTBridgeImpl.java:49) 
    at com.google.gwt.core.client.GWT.create(GWT.java:97) 
    at com.google.gwt.i18n.client.LocaleInfo.<clinit>(LocaleInfo.java:37) 
    at com.google.gwt.user.client.ui.HasHorizontalAlignment.<clinit>(HasHorizontalAlignment.java:123) 
    at com.google.gwt.user.client.ui.VerticalPanel.<init>(VerticalPanel.java:31) 
    at com.google.gwt.sample.stockwatcher.client.StockWatcher.<init>(StockWatcher.java:29) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:525) 
    at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:465) 
    at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:375) 
    at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200) 
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525) 
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363) 
    at java.lang.Thread.run(Thread.java:722) 

11:26:27.640 [ERROR] [stockwatcher] Unable to load module entry point class com.google.gwt.sample.stockwatcher.client.StockWatcher (see associated exception for details) 
com.google.gwt.dev.shell.BrowserChannel$RemoteDeathError: Remote connection lost 
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:356) 
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218) 
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289) 
    at com.google.gwt.dev.shell.ModuleSpace.displayErrorGlassPanel(ModuleSpace.java:616) 
    at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:401) 
    at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200) 
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525) 
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363) 
    at java.lang.Thread.run(Thread.java:722) 
Caused by: com.google.gwt.dev.shell.BrowserChannelException: Invalid message type PROTOCOL_VERSION received waiting for return. 
    at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:350) 
    at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218) 
    at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561) 
    at com.google.gwt.dev.shell.ModuleSpace.invokeNativeVoid(ModuleSpace.java:289) 
    at com.google.gwt.dev.shell.ModuleSpace.displayErrorGlassPanel(ModuleSpace.java:616) 
    at com.google.gwt.dev.shell.ModuleSpace.onLoad(ModuleSpace.java:401) 
    at com.google.gwt.dev.shell.OophmSessionHandler.loadModule(OophmSessionHandler.java:200) 
    at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:525) 
    at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363) 
    at java.lang.Thread.run(Thread.java:722) 

11:26:27.959 [ERROR] [stockwatcher] Failed to load module 'stockwatcher' from user agent 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2' at localhost:52343 

Jest to kod z StockWatcher.java:

package com.google.gwt.sample.stockwatcher.client; 

import com.google.gwt.core.client.EntryPoint; 
import com.google.gwt.core.client.GWT; 
import com.google.gwt.event.dom.client.ClickEvent; 
import com.google.gwt.event.dom.client.ClickHandler; 
import com.google.gwt.event.dom.client.KeyCodes; 
import com.google.gwt.event.dom.client.KeyPressEvent; 
import com.google.gwt.event.dom.client.KeyPressHandler; 
import com.google.gwt.i18n.client.DateTimeFormat; 
import com.google.gwt.i18n.client.NumberFormat; 
import com.google.gwt.user.client.Random; 
import com.google.gwt.user.client.Timer; 
import com.google.gwt.user.client.Window; 
import com.google.gwt.user.client.ui.Button; 
import com.google.gwt.user.client.ui.FlexTable; 
import com.google.gwt.user.client.ui.HorizontalPanel; 
import com.google.gwt.user.client.ui.Label; 
import com.google.gwt.user.client.ui.RootPanel; 
import com.google.gwt.user.client.ui.TextBox; 
import com.google.gwt.user.client.ui.VerticalPanel; 

import java.util.ArrayList; 
import java.util.Date; 

public class StockWatcher implements EntryPoint { 



private static final int REFRESH_INTERVAL = 5000; 
    private VerticalPanel mainPanel = new VerticalPanel(); //line 29 
    private FlexTable stocksFlexTable = new FlexTable(); 
    private HorizontalPanel addPanel = new HorizontalPanel(); 
    private TextBox newSymbolTextBox = new TextBox(); 
    private Button addStockButton = new Button("Add"); 
    private Label lastUpdatedLabel = new Label(); 
    private ArrayList<String> stocks = new ArrayList<String>(); 
    private StockWatcherConstants constants = GWT.create(StockWatcherConstants.class); 

    /** 
    * Entry point method. 
    */ 
    public void onModuleLoad() { 
    // Set the window title, the header text, and the Add button text. 
    Window.setTitle(constants.stockWatcher()); 
    RootPanel.get("appTitle").add(new Label(constants.stockWatcher())); 
    addStockButton = new Button(constants.add()); 

    // Create table for stock data. 
    stocksFlexTable.setText(0, 0, constants.symbol()); 
    stocksFlexTable.setText(0, 1, constants.price()); 
    stocksFlexTable.setText(0, 2, constants.change()); 
    stocksFlexTable.setText(0, 3, constants.remove()); 

    // Add styles to elements in the stock list table. 
    stocksFlexTable.setCellPadding(6); 
    stocksFlexTable.getRowFormatter().addStyleName(0, "watchListHeader"); 
    stocksFlexTable.addStyleName("watchList"); 
    stocksFlexTable.getCellFormatter().addStyleName(0, 1, "watchListNumericColumn"); 
    stocksFlexTable.getCellFormatter().addStyleName(0, 2, "watchListNumericColumn"); 
    stocksFlexTable.getCellFormatter().addStyleName(0, 3, "watchListRemoveColumn"); 

    // Assemble Add Stock panel. 
    addPanel.add(newSymbolTextBox); 
    addPanel.add(addStockButton); 
    addPanel.addStyleName("addPanel"); 

    // Assemble Main panel. 
    mainPanel.add(stocksFlexTable); 
    mainPanel.add(addPanel); 
    mainPanel.add(lastUpdatedLabel); 

    // Associate the Main panel with the HTML host page. 
    RootPanel.get("stockList").add(mainPanel); 

    // Move cursor focus to the input box. 
    newSymbolTextBox.setFocus(true); 

    // Setup timer to refresh list automatically. 
    Timer refreshTimer = new Timer() { 
     @Override 
     public void run() { 
     refreshWatchList(); 
     } 
    }; 
    refreshTimer.scheduleRepeating(REFRESH_INTERVAL); 

    // Listen for mouse events on the Add button. 
    addStockButton.addClickHandler(new ClickHandler() { 
     public void onClick(ClickEvent event) { 
     addStock(); 
     } 
    }); 

    // Listen for keyboard events in the input box. 
    newSymbolTextBox.addKeyPressHandler(new KeyPressHandler() { 
     public void onKeyPress(KeyPressEvent event) { 
     if (event.getCharCode() == KeyCodes.KEY_ENTER) { 
      addStock(); 
     } 
     } 
    }); 

    } 

    /** 
    * Add stock to FlexTable. Executed when the user clicks the addStockButton or 
    * presses enter in the newSymbolTextBox. 
    */ 
    private void addStock() { 
    final String symbol = newSymbolTextBox.getText().toUpperCase().trim(); 
    newSymbolTextBox.setFocus(true); 

    // Stock code must be between 1 and 10 chars that are numbers, letters, or dots. 
    if (!symbol.matches("^[0-9a-zA-Z\\.]{1,10}$")) { 
     Window.alert("'" + symbol + "' is not a valid symbol."); 
     newSymbolTextBox.selectAll(); 
     return; 
    } 

    newSymbolTextBox.setText(""); 

    // Don't add the stock if it's already in the table. 
    if (stocks.contains(symbol)) 
     return; 

    // Add the stock to the table. 
    int row = stocksFlexTable.getRowCount(); 
    stocks.add(symbol); 
    stocksFlexTable.setText(row, 0, symbol); 
    stocksFlexTable.setWidget(row, 2, new Label()); 
    stocksFlexTable.getCellFormatter().addStyleName(row, 1, "watchListNumericColumn"); 
    stocksFlexTable.getCellFormatter().addStyleName(row, 2, "watchListNumericColumn"); 
    stocksFlexTable.getCellFormatter().addStyleName(row, 3, "watchListRemoveColumn"); 

    // Add a button to remove this stock from the table. 
    Button removeStockButton = new Button("x"); 
    removeStockButton.addStyleDependentName("remove"); 
    removeStockButton.addClickHandler(new ClickHandler() { 
     public void onClick(ClickEvent event) { 
     int removedIndex = stocks.indexOf(symbol); 
     stocks.remove(removedIndex); 
     stocksFlexTable.removeRow(removedIndex + 1); 
     } 
    }); 
    stocksFlexTable.setWidget(row, 3, removeStockButton); 

    // Get the stock price. 
    refreshWatchList(); 

    } 

    /** 
    * Generate random stock prices. 
    */ 
    private void refreshWatchList() { 
    final double MAX_PRICE = 100.0; // $100.00 
    final double MAX_PRICE_CHANGE = 0.02; // +/- 2% 

    StockPrice[] prices = new StockPrice[stocks.size()]; 
    for (int i = 0; i < stocks.size(); i++) { 
     double price = Random.nextDouble() * MAX_PRICE; 
     double change = price * MAX_PRICE_CHANGE 
      * (Random.nextDouble() * 2.0 - 1.0); 

     prices[i] = new StockPrice(stocks.get(i), price, change); 
    } 

    updateTable(prices); 
    } 

    /** 
    * Update the Price and Change fields all the rows in the stock table. 
    * 
    * @param prices Stock data for all rows. 
    */ 
    private void updateTable(StockPrice[] prices) { 
    for (int i = 0; i < prices.length; i++) { 
     updateTable(prices[i]); 
    } 

// // Display timestamp showing last refresh. 
// lastUpdatedLabel.setText("Last update : " 
//  + DateTimeFormat.getMediumDateTimeFormat().format(new Date())); 

    } 

    /** 
    * Update a single row in the stock table. 
    * 
    * @param price Stock data for a single row. 
    */ 
    private void updateTable(StockPrice price) { 
    // Make sure the stock is still in the stock table. 
    if (!stocks.contains(price.getSymbol())) { 
     return; 
    } 

    int row = stocks.indexOf(price.getSymbol()) + 1; 

    // Format the data in the Price and Change fields. 
    String priceText = NumberFormat.getFormat("#,##0.00").format(
     price.getPrice()); 
    NumberFormat changeFormat = NumberFormat.getFormat("+#,##0.00;-#,##0.00"); 
    String changeText = changeFormat.format(price.getChange()); 
    String changePercentText = changeFormat.format(price.getChangePercent()); 

    // Populate the Price and Change fields with new data. 
    stocksFlexTable.setText(row, 1, priceText); 
    Label changeWidget = (Label)stocksFlexTable.getWidget(row, 2); 
    changeWidget.setText(changeText + " (" + changePercentText + "%)"); 

    // Change the color of text in the Change field based on its value. 
    String changeStyleName = "noChange"; 
    if (price.getChangePercent() < -0.1f) { 
     changeStyleName = "negativeChange"; 
    } 
    else if (price.getChangePercent() > 0.1f) { 
     changeStyleName = "positiveChange"; 
    } 

    changeWidget.setStyleName(changeStyleName); 
    } 

} 

Javier

+0

co robisz w tym wierszu: "com.google.gwt.sample.stockwatcher.client.StockWatcher. (StockWatcher.java:29)"? – Stefan

+0

@Stefan Właśnie dodałem kod StockWatcher.java. Wiersz 29 jest komentowany. – ziiweb

Odpowiedz

7

odniesienie do linii 29 w ślad stosu może wskazywać, że

private StockWatcherConstants constants = 
    GWT.create(StockWatcherConstants.class); 

nie można utworzyć instancji. Nie mogłem znaleźć tekstu dla StockWatcherConstants w Twoim poście.

Jako Niemiec, który używa GWT z lokalizacją - zwykle z Messages zamiast Constants - Nie przypominam sobie, aby widział dokładnie ten sam błąd, ale są pewne typowe pułapki.

Upewnij się, że pliki właściwości są naprawdę zakodowane przy użyciu UTF-8. Zgodnie z dokumentacją GWT nie jest ona zgodna ze standardową Javą.

Upewnij się również, że Twój telefon Module.gwt.xml jest prawidłowo skonfigurowany. Twoja aplikacja powinna dziedziczyć moduł internacjonalizacji.

<inherits name="com.google.gwt.i18n.I18N"/> 

Ponadto należy zadeklarować dostępne ustawienia regionalne i wybrać wartość domyślną.

<extend-property name="locale" values="de"/> 
<!-- <extend-property name="locale" values="en"/> --> 
<!-- <extend-property name="locale" values="zh"/> --> 
<set-property-fallback name="locale" value="de"/> 

Aby zmienić ustawienia regionalne, należy ponownie załadować aplikację. Locale są kompilowane w oddzielne pliki JavaScript.

Jeśli nie chcesz polegać na nagłówku HTTP do lokalizacji, możesz ustawić ustawienia regionalne z pliku cookie.

String localeCookie = Cookies.getCookie(LocaleInfo.getLocaleCookieName()); 

if(localeCookie != null) { 
    setLocale(localeCookie); 
} 

Następna deklaracja jest wymagana w innym miejscu.

protected void setLocale(String targetLocale) { 

    if (LocaleInfo.getCurrentLocale().getLocaleName().equals(targetLocale)) 
    return; 

    Set<String> availableLocales = 
    new HashSet<String>(Arrays.asList(LocaleInfo.getAvailableLocaleNames())); 
    if (! availableLocales.contains(targetLocale)) 
    return; 

    Cookies.setCookie(LocaleInfo.getLocaleCookieName(), targetLocale, 
    new Date(new Date().getTime() + COOKIE_LIFETIME)); 

    Window.Location.reload(); 
} 

Tylko upewnij się również zadeklarować cookie lokalizacji w Module.gwt.xml.

<set-configuration-property name="locale.cookie" value="GWTlocale"/> 

Możesz użyć tej funkcji setLocale() do zmiany ustawień regionalnych w odpowiedzi na zdarzenie interfejsu użytkownika. Jednak z powodu przeładowania stracisz wszystkie informacje o stanie.

Jeśli używasz Places, możesz użyć drugiego cookie, aby wrócić do miejsca, w którym byłeś.

eventBus.addHandler(PlaceChangeEvent.TYPE, new PlaceChangeEvent.Handler() { 
    @Override 
    public void onPlaceChange(PlaceChangeEvent event) { 
     Cookies.setCookie(HISTORY_COOKIE, 
     historyMapper.getToken(event.getNewPlace()), 
     new Date(new Date().getTime() + COOKIE_LIFETIME)); 
    } 
}); 

Po uruchomieniu aplikacja będzie przeglądać plik cookie, a presto - to samo miejsce w nowym języku.

String lastToken = Cookies.getCookie(HISTORY_COOKIE); 
Place defaultPlace = 
    (lastToken != null ? historyMapper.getPlace(lastToken) : Place.NOWHERE); 

if (defaultPlace == Place.NOWHERE) 
    defaultPlace = new BestPlaceToStartYourApplication(); 

historyHandler.register(placeController, eventBus, defaultPlace); 
historyHandler.handleCurrentHistory(); 

Ta odpowiedź jest nieco bardziej wyczerpująca, ponieważ Twoje pytanie pozostało bez odpowiedzi przez tak długi czas. Mam nadzieję, że zaczynasz od internacjonalizacji w GWT.

+0

Dziękuję, dla mnie brakowało tej linii w pliku module.gwt.xml Nie widziałem tej linii w samouczku, ale musi być tam najwyraźniej. – FloatingCoder