GWT Drag and Drop

Das Projekt unter http://code.google.com/p/gwt-dnd/ gehört mit den zu den bekanntesten Drag & Drop Bibliotheken für GWT. Die von Fred Allen-Sauer geschriebene Bibliothek ist ordentlich mit Beispielen hinterlegt, sodass der Einstieg einfach ist. Ein kleines Beispiel soll die Bibliothek demonstrieren.

a) Nach dem Einbinden der Jar-Datei ist in der XML-Datei für GWT folgendes einzutragen:

<inherits name='com.allen_sauer.gwt.dnd.gwt-dnd'/>

b) Von http://code.google.com/p/gwt-dnd/source/browse/trunk/DragDrop/#DragDrop/war/images nimmt man die Grafik row-dragger-8.gif passend etwa in das WEB-INF/images mit auf und schaut auf den URL-Eintrag in der CSS, dass der Pfad passt.

c) Von http://code.google.com/p/gwt-dnd/source/browse/trunk/DragDrop/#DragDrop/demo/com/allen_sauer/gwt/dnd/demo/client/example/flextable kopiert man die Dateien

  • FlexTableRowDragController
  • FlexTableRowDropController
  • FlexTableUtil

in das eigene GWT-Projekt.

In onModuleLoad() kann es dann so aussehen:

AbsolutePanel panel = new AbsolutePanel();
panel.setPixelSize(450, 300);
panel.addStyleName(„demo-FlexTableRowExample“);

FlexTableRowDragController dragController = new FlexTableRowDragController( panel );
FlexTable table = new FlexTable();

table.addStyleName( „demo-flextable“ );

HTML handle1 = new HTML( „<b>Heinzelmann</b> (100 €)“ );
handle1.addStyleName( „demo-drag-handle“ );
table.setWidget( 0, 0, handle1 );
dragController.makeDraggable( handle1 );

HTML handle2 = new HTML( „<b>Wumme</b> (200 €)“ );
handle2.addStyleName( „demo-drag-handle“ );
table.setWidget( 1, 0, handle2 );
dragController.makeDraggable( handle2 );

HTML handle3 = new HTML( „<b>Fred</b> (90 €)“ );
handle3.addStyleName( „demo-drag-handle“ );
table.setWidget( 2, 0, handle3 );
dragController.makeDraggable( handle3 );

panel.add(table, 10, 20);
FlexTableRowDropController dropController = new FlexTableRowDropController(table);
dragController.registerDropController(dropController); 

RootPanel.get().add( panel );

Anschließend haben wir eine Webseite mit

Heinzelmann (100 €)

Wumme (200 €)

Fred (90 €)

wobei wir die 3 Einträge in der Reihenfolge verschieben können.

Denormalisierung für schnelle Key/Value Speichersysteme

RDBMS kommen im distributed Cloud-Computing selten vor. Daher muss man auch die Datenhaltung überdenken. Ein Blog-Eintrag diskutiert die Änderungen sehr gut: http://highscalability.com/how-i-learned-stop-worrying-and-love-using-lot-disk-space-scale. Im Prinzip geht es darum, aus Joins zu verzichten, und Daten in den verschiedenen Entities zu duplizieren. Die Erfahrung habe ich bei meinen GWT und GAE/J Projekt ebenfalls gemacht. Es führt zu weniger Lesezugriffen insgesamt, wenn man die Daten lokal in der Entity hält und nicht erst aus verschiedenen Entities zusammensucht, wie man bei normalisierten relationalen Modellen tut. (Außerdem ist es bei vielen lese-Zugriffen auch billiger, die Daten an einer Stelle zu haben, anstatt sie von verschiedenen Stellen über Lesezugriffe, die jeweils Kosten nach sich ziehen, einzusammeln.)

In meinen GWT-GAE/J-Projekt habe ich noch einen anderen Ansatz, die Zugriffe auf die Big-Table zu minimieren. Grundsätzlich: Alle GWT-RPC Implementierungen sind Fassaden, die auf Services zurückgreifen (Googe Guice injiziert diese in die RPC-Fassaden). Für diese Endpoints gibt es dann noch einmal einen Caching-Dekorator als eine Art Caching-Aspekt, der sich wie ein Proxy um die eigentlichen RPC-Implementierungen legt. Diese speichert relevante Daten im MemCache zwischen und minimiert so (langsame) Zugriffe auf die Big-Table. Bei Schreibzugriffen löscht der Caching-Proxy die relevanten Daten aus dem Cache, sodass sie neu geladen werden müssen. Das ist einfach und fix.

Groovy 1.7 und Groovy Eclipse 2.0

Ein paar Tage ist es schon her, da wurde Groovy 1.7 veröffentlicht. Die Neuerungen gibt es unter http://docs.codehaus.org/display/GROOVY/Groovy+1.7+release+notes. Im Wesentlichen sind es die Unterstützung von geschachtelten und anonymen inneren Klassen, ein paar AST-Sachen.

Ganz frisch ist nun das Update der Groovy IDE auf Eclipse Basis. Die Version 2.0 ist fertig und ist nahezu ein vollständiger rewrite. Die News listet http://docs.codehaus.org/display/GROOVY/Groovy-Eclipse+2.0.0+New+and+Noteworthy auf. Weiterhin mit bunten Bildern:

Java 6 Update 18

Die Änderungen http://java.sun.com/javase/6/webnotes/6u18.html sind vielfältig. Zum einen für die Systemkonfigurationen:

Dann:

Im JDK gibt es ein Update der Datenbank

Aus dem Bereich XML:

Und vieles mehr im Bereich Tuning und Fehlerbehebung.

Ant 1.8.0RC1 ist auf dem Weg

Ant 1.7 gibt’s ja schon gefühlte ewige Zeit und bei Ant, dem make des 2.0 Zeitalters, steht ein Update ein. Nichts großes, sondern eher Detailverbesserungen:

Apache Ant 1.8.0RC1 is now available for download .

  • a new top level element extension-point allows build files to be extended with custom targets more easily
  • if and unless attributes will be evaluated according to the values of the properties entered if these properties evaluate to true, false, on, off
  • Ant now requires Java 1.4 or later
  • new task include provides an alternative to <import> that should be preferred when you don’t want to override any targets
  • numerous bug fixes and improvements as documented in Bugzilla and in WHATSNEW

While in open source projects a final release date strongly depends on the free time of the volunteers/committers, the final release is expected one to two months maximum after this RC. So Ant 1.8.0 is expected between mid February and mid March 2010.

Mit dem MVP-Modell GWT-Anwendungen entwickeln

Unter http://code.google.com/webtoolkit/doc/latest/tutorial/mvp-architecture.html widmet sich Google nun etwas mehr der Architektur von GWT-Anwendungen. Der Artikel „Large scale application development and MVP“ beschreibt, wie die drei Teile Model, View und Presenter zusammenarbeiten und getestet werden können. Komplexer wird das Bsp. da noch History-Management und der Event-Bus mit ins Boot kommen.

Im Quellcode auf der Seite gibt es einige Fehler durch ein falsch verarbeitet <. So steht etwa

  public interface Display extends HasValue> {
    HasClickHandlers getAddButton();
    HasClickHandlers getDeleteButton();
    HasClickHandlers getList();
    void setData(List data);
    int getClickedRow(ClickEvent event);
    List getSelectedRows();
    Widget asWidget();
  }

statt

  public interface Display {
    HasClickHandlers getAddButton();
    HasClickHandlers getDeleteButton();
    HasClickHandlers getList();
    void setData(List<String> data);
    int getClickedRow(ClickEvent event);
    List<Integer> getSelectedRows();
    Widget asWidget();
  }