2017-09-19 2 views
1

Die Hauptsache meines Problems ist, dass ich will Daten in mein Raster von der Tastatur einsetzen. Einige Daten werden aus der Datenbank geladen und der Benutzer kann ändern (kann auch die geladenen Daten ändern) oder die neuen Daten in das Grid einfügen (manuell). Dann möchte ich aus den Spalten in den letzten Reihen, die Ergebnisse sehen (Überprüfen Sie die Ergebnisse in meinem Bild) - Ergebnisse bedeutet, dass die Zahl in Zeilen, in denen in der ersten Spalte sind Daten wie - Summe, Durchschnitt, min, max ...Set Ergebnisse von mathematischen Operationen in Vaadin Grid in Echtzeit (manuell einfügen), Am Vaadin 7

enter image description here

Also, wenn ich in der dritten Zeile klicken, in Spalte zB Person 3, und wenn ich den Wert von 5 bis 6 und in dieser Zeit ändern werde die Summe 16 sein wird, wird maximal 6 sein, wird min 1 und durchschnittlich 3,2 sein

Mein Code von Grid:

Grid grid = new Grid(); 

IndexedContainer container = new IndexedContainer(); 
grid.setContainerDataSource(container); 

container.addContainerProperty("September", String.class, null); 
container.addContainerProperty("Person1", String.class, null); 
container.addContainerProperty("Person2", String.class, null); 
container.addContainerProperty("Person3", String.class, null); 
container.addContainerProperty("Person4", String.class, null); 
container.addContainerProperty("Person5", String.class, null); 
container.addContainerProperty("Person6", String.class, null); 
container.addContainerProperty("Person7", String.class, null); 
container.addContainerProperty("Person8", String.class, null); 

for(int i = 0; i < 10; i++) 
    container.addItem(i); 

Item item = container.getItem(1); 

item.getItemProperty("September").setValue("1.9.2017 Piatok"); 

item = container.getItem(2); 
item.getItemProperty("September").setValue("2.9.2017 Sobota"); 

.... 

Ich versuchte, die addValueChangeListener an das Netz (Container)

container.addValueChangeListener(e -> { 

     int sum = 0; 
     for(int i = 0; i < 5; i++) 
     { 
     Item item = container.getItem(i); 
     sum += (Integer) item.getItemProperty("Person3").getValue(); 
     } 

     item = container.getItem(6); 
     item.getItemProperty("Person3").setValue(sum); 

    }); 

Aber ich erhalte die Fehlermeldung hinzuzufügen:

sep 15, 2017 4:16:21 PM com.vaadin.server.DefaultErrorHandler doDefault 
SEVERE: 
com.vaadin.data.Buffered$SourceException 
    at com.vaadin.ui.AbstractField.setValue(AbstractField.java:546) 
    at com.vaadin.ui.AbstractField.setValue(AbstractField.java:468) 
    at com.vaadin.ui.AbstractTextField.changeVariables(AbstractTextField.java:205) 
    at com.vaadin.server.communication.ServerRpcHandler.changeVariables(ServerRpcHandler.java:616) 
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:463) 
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:406) 
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273) 
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90) 
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41) 
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1422) 
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:380) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689) 
    at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:225) 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676) 
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) 
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) 
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) 
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1174) 
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511) 
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1106) 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213) 
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:119) 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134) 
    at org.eclipse.jetty.server.Server.handle(Server.java:524) 
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319) 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253) 
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273) 
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95) 
    at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148) 
    at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.StackOverflowError 
    at java.util.Hashtable.get(Hashtable.java:366) 
    at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(IndexedContainer.java:848) 
    at my.vaadin.app.MyUI.lambda$11(MyUI.java:3931) 
    at com.vaadin.data.util.IndexedContainer.firePropertyValueChange(IndexedContainer.java:528) 
    at com.vaadin.data.util.IndexedContainer.access$1000(IndexedContainer.java:63) 
    at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.setValue(IndexedContainer.java:867) 
    at my.vaadin.app.MyUI.lambda$11(MyUI.java:3931) 

Problem ist, wenn ich versuche, 2 und mehr Zellen zu ändern ...

container.addValueChangeListener(e -> { 


       Item item = container.getItem(6); 

       if(!e.getProperty().equals(item.getItemProperty("Person3"))) 
         item.getItemProperty("Person3").setValue(54 + ""); 

       if(!e.getProperty().equals(item.getItemProperty("Person4"))) 
        item.getItemProperty("Person4").setValue(65 + ""); 

      }); 

Wie kann ich es beheben?

enter image description here

Das ist das Problem, ich will diese Fußzeile nicht haben am Netz immer sichtbar. Ich möchte die Fußzeilen nur sehen, wenn ich am Ende des Rasters angelangt bin. Verstehst du das?

+0

Sie diesen Fehler erhalten, weil Sie die Feldwerte ändern In einem Wertänderungs-Listener werden also andere Änderungsereignisse generiert, sodass der Listener unbegrenzt ausgelöst wird. Ich denke, der einfachste Weg ist, das gleiche zu tun, aber 5 Fußzeilen zu verwenden. Dies verhindert auch, dass der Benutzer diese _calculated_-Werte manuell bearbeiten kann. – Morfic

+0

@Morfic aber diese Fußzeile Zeilen sind immer sichtbar, wenn ich das Raster scrollen ... Und ich will das nicht ... Oder? – Ady96

+0

@Morfic Wenn ich auf diese Weise wählen muss, brauche ich etwas, das die Fußzeile auf die eine Position setzen kann, die beste wird sein, wenn die Fußzeile am unteren Rand des Rasters sein wird. Und dann können Sie innerhalb des Rasters scrollen, und die Fußzeile bleibt unten. – Ady96

Antwort

2

jetzt Angenommen, Sie dachte ich heraus, warum Sie einen SOE bekommen durch eine ValueChangeListener mit zu Aktualisieren Sie die Summenzeile, können Sie dieses Problem mit einem ähnlichen Ansatz überwinden, indem Sie einen Editor CommitHandler, wenn die Editor-Änderungen gespeichert werden, wird die Summenzeile aktualisiert.Aus Gründen der Kürze unten nur die Probe berechnet die Summe, aber Sie können für den Rest Ihrer Operation ähnliche Logik anwenden:

public class GridWithCalculatedRow extends VerticalLayout { 

    public GridWithCalculatedRow() { 
     // indexed container allowing the definition of custom properties 
     IndexedContainer container = new IndexedContainer(); 
     container.addContainerProperty("September", String.class, null); 
     container.addContainerProperty("Person1", Integer.class, 0); 
     container.addContainerProperty("Person2", Integer.class, 0); 
     container.addContainerProperty("Person3", Integer.class, 0); 


     // add some dummy data 
     Random random = new Random(); 
     for (int i = 0; i < 5; i++) { 
      Item item = container.addItem(i); 
      item.getItemProperty("September").setValue(String.valueOf(i)); 
      item.getItemProperty("Person1").setValue(random.nextInt(10)); 
      item.getItemProperty("Person2").setValue(random.nextInt(10)); 
      item.getItemProperty("Person3").setValue(random.nextInt(10)); 
     } 

     Item sumItem = container.addItem(6); 
     sumItem.getItemProperty("September").setValue("Sum"); 

     // basic grid setup 
     Grid grid = new Grid(); 
     grid.setContainerDataSource(container); 
     grid.getColumn("September").setEditable(false); 
     addComponent(grid); 

     // initial sum 
     updateSum(container, sumItem); 

     // disable editing of sum item 
     grid.addItemClickListener(event -> { 
      if (event.getItemId().equals(6)) { 
       grid.setEditorEnabled(false); 
      } else { 
       grid.setEditorEnabled(true); 
      } 
     }); 


     // editor commit handler to update the sum 
     grid.getEditorFieldGroup().addCommitHandler(new FieldGroup.CommitHandler() { 
      @Override 
      public void preCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException { 
       // nothing to do here for now 
      } 

      @Override 
      public void postCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException { 
       updateSum(container, sumItem); 
      } 
     }); 

    } 

    // recalculate all sums and update the sum item 
    private void updateSum(IndexedContainer container, Item sumItem) { 
     Integer person1Sum = 0; 
     Integer person2Sum = 0; 
     Integer person3Sum = 0; 

     // calculate sums 
     for (int i = 0; i < 5; i++) { 
      Item item = container.getItem(i); 
      person1Sum += (Integer) item.getItemProperty("Person1").getValue(); 
      person2Sum += (Integer) item.getItemProperty("Person2").getValue(); 
      person3Sum += (Integer) item.getItemProperty("Person3").getValue(); 

     } 

     // update grid item 
     sumItem.getItemProperty("Person1").setValue(person1Sum); 
     sumItem.getItemProperty("Person2").setValue(person2Sum); 
     sumItem.getItemProperty("Person3").setValue(person3Sum); 
    } 
} 

Ergebnis: vaadin-grid-with-calculated-row

+0

Danke! :) Und ich habe letzte Frage. Kann ich dies ohne gepufferten Editor-Modus tun? – Ady96

+0

@ Ady96 Ich habe bisher nicht im un-gepufferten Modus verwendet. Auf den ersten Blick verhält es sich anders und der Commit-Handler wird nicht ausgelöst, also kann ich es nicht wirklich sagen. Es braucht mehr Untersuchung – Morfic

3

Dies wird bereits in Using Vaadin 7.4.9 - How to delete data from the grid beantwortet Die Ursache ist die gleiche, Sie rufen container.setValue innerhalb der container.addValueChangeListener, was zu einer Endlosschleife.

Sie können nicht anrufen item.getItemProperty("Person3").setValue(sum); innerhalb des Zuhörers.

Sie müssen prüfen, ob das Element, das Sie gerade setzen nicht bereits das letzte Mal, stellen Sie Ihre Schleife besucht. die folgende Stellen Sie sich vor:

int otherValue = 10; 

public setValue(int newValue) { 
    int sum = newValue + otherValue; //this is your sum 
    setValue(sum); //of course this causes a StackOverFlowError 
} 

Hier ist eine Lösung, die für Ihr Projekt arbeiten konnten:

if(!e.getProperty().equals(item.getItemProperty("Person3")) 
    item.getItemProperty("Person3").setValue(sum); 
+0

Das ist richtig, aber ich brauche Daten von allen Eigenschaften nicht nur eins :) – Ady96

+0

Der einfachste Weg für Sie wäre, das Gitter in ein InputGrid und ein ResultGrid zu teilen. –

+0

Oder 'THE BAD SOLUTION' haben einen booleschen Wert, der Ihnen sagt, wenn Sie eine Bearbeitung innerhalb des' ValueChangeListener' vornehmen. Dies wird natürlich abgeraten, aber "nützlich". – Shirkam