2017-03-26 4 views
1

Ich habe eine TableView mit dem Namen tableVerre und ich möchte jede Zeile für ein Kriterium überprüft haben (stock Spaltenwert) und führen Sie einige Code auf sie als ich scroll, also schrieb ich dieser Code, aber es macht das Programm eine Menge CPU-Zeit zu verbrauchen, ich bin nicht vertraut mit Lambda-Ausdrücke so gibt es eine einfachere Möglichkeit, dies zu schreiben? :ScrollEvent auf TableView dauert zu viel von der CPU-Zeit

tableVerre.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() { 

    @Override 
    public void handle(ScrollEvent scrollEvent) { 

    stock.setCellFactory(column -> { 

    return new TableCell<VerreFX, Number>() { 
     @Override 
     protected void updateItem(Number item, boolean empty) { 
     super.updateItem(item, empty); 

      TableRow<VerreFX> currentRow = getTableRow(); 

      if (empty || item == null) { 
       setText(""); 
       setGraphic(null); 
       currentRow.setStyle(tableVerre.getStyle()); 
      } else { 
       setText(getItem().toString()); 
      } 

      if (!isEmpty()) { 
       if ((int) item == 0 && st.getVerresBOX()) currentRow.setStyle("-fx-background-color:lightcoral"); 
      } 
     } 
    }; 
}); 

      } 
    }); 
+0

Warum ersetzen Sie die 'cellFactory' im Scroll-Handler? Wahrscheinlich werden die Zellen nicht einmal neu erstellt, es sei denn, Sie ändern die Größe der Tabelle ... – fabian

+0

Wo würde ich es hinstellen? Übrigens werden die Zellen neu erstellt, ohne die Tabelle zu verändern. –

+0

Die Zellen werden neu erstellt, wenn Sie eine neue Zellenfabrik (AFAIK) einrichten. Wenn Sie die Zellenfactory nicht ständig ersetzen, werden sie einfach wiederverwendet (die Methode 'updateItem (...)' wird bei vorhandenen Zellen aufgerufen), während der Benutzer scrollt. Offensichtlich ist das Aufrufen von 'updateItem()' viel weniger leistungsintensiv als das wiederholte Ersetzen aller Zellen. –

Antwort

2

Die Tabellenansicht werden die Zellen beim Scrollen des Nutzers wiederverwenden und wird updateItem automatisch auf die Zellen rufen, wenn sie für neue Objekte wiederverwendet werden. Daher sollten Sie die Zellenfactory nur einmal festlegen und dann nur die Tabellenansicht ausführen lassen, um die Aufgabe auszuführen, für die sie vorgesehen ist. Sie können die Zellenfactory in der Methode initialize() festlegen, wenn Sie FXML verwenden, oder nur dort, wo Sie die Tabelle und die Spalten andernfalls erstellen.

Ihre Zellimplementierung ist nicht ganz korrekt: Da eine Zelle wiederverwendet werden kann, um beliebige zwei verschiedene Elemente beliebig anzuzeigen, müssen Sie alle möglichen Bedingungen berücksichtigen. Wenn in Ihrer Implementierung eine Zelle einen Artikel anzeigt, für den item.intValue()==0 und dann erneut verwendet wird, um einen Artikel anzuzeigen, für den item.intValue() != 0 angezeigt wird, wird der Stil nicht korrekt aktualisiert.

Beachten Sie auch, dass Sie eine Number in eine int "umwandeln" sollten, indem Sie intValue() aufrufen.

TableColumn<VerreFX, Number> stock ; 

// ... 

stock.setCellFactory(column -> new TableCell<VerreFX, Number>() { 
    @Override 
    protected void updateItem(Number item, boolean empty) { 
     super.updateItem(item, empty); 

     TableRow<VerreFX> currentRow = getTableRow(); 

     if (empty || item == null) { 
      setText(""); 
      setGraphic(null); 
      currentRow.setStyle(tableVerre.getStyle()); 
     } else { 
      setText(getItem().toString()); 
     } 

     if (!isEmpty()) { 
      if (item.intValue() == 0 && st.getVerresBOX()) { 
       currentRow.setStyle("-fx-background-color:lightcoral"); 
      } else { 
       currentRow.setStyle(tableVerre.getStyle()); 
      } 
     } 
    } 
}); 

Sie sollten den Scroll-Event-Handler vollständig entfernen können.

+0

Ja, ich benutze fxml und setze die Zellenfactory in initialize() war genau mein Ansatz, aber sobald eine Zeile den Stil ändert, wird jede Zelle, die in dieser Zeile angezeigt wird, den gleichen Stil haben! hat sich nicht selbst aktualisiert. –

+0

Ist das nicht nur wegen des Fehlers, auf den ich hingewiesen habe? –

+0

Es ist, was Sie erwähnt haben, aber ich habe diesen Fehler nicht! Ich verwendete, und ich fand eine Lösung (das Aktualisieren von Zellen auf jedem Bildlaufereignis), die CPU-Zeit verbraucht, die der Code in der Frage ist, und ich fand eine Möglichkeit, das durch das Aktualisieren der Zellen zu verhindern, wenn das Bildlauf beendet wird. Danke James –

1

Erstens, Sie haben nicht über die CPU-Zeit hinweg mit Ihnen gearbeitet, da Sie nicht alle Scrollsituationen abdecken konnten. Wenn der Benutzer mit der Taste Down/Up blättert oder die Bildlaufleiste verwendet, wird das Scroll-Ereignis nicht ausgelöst. So müssen Sie zwei weitere EventFilter hinzufügen, die erste wird das Scrollen mit der Bildlaufleiste behandeln.

tableVerre.addEventFilter(MouseEvent.MOUSE_CLICKED,(
      MouseEvent event)-> 
    { 
     if ((event.getTarget() instanceof TableColumnHeader) | event.isDragDetect()) { 
      System.err.println("Mouse Draged : " + event.toString()); 

      stock.setCellFactory((TableColumn<VerreFX, Number> column) -> { 

       return new TableCell<VerreFX, Number>() { 
        @Override 
        protected void updateItem(Number item, boolean empty) { 
         super.updateItem(item, empty); 

         TableRow<VerreFX> currentRow = getTableRow(); 

         if (empty || item == null) { 
          setText(""); 
          setGraphic(null); 
          currentRow.setStyle(tableVerre.getStyle()); 
         } else { 
          setText(getItem().toString()); 
         } 

         if (!isEmpty()) { 
          if ((int) item == 0 && st.getVerresBOX()) { 
           currentRow.setStyle("-fx-background-color:lightcoral"); 
          } 
         } 
        } 
       }; 
      }); 
     } 
    }); 

Und der zweite wird das Scrollen mit der Tastatur Taste DOWN/UP behandeln.

tableVerre.addEventFilter(KeyEvent.KEY_PRESSED,new EventHandler<KeyEvent>(){ 
    @Override 
    public void handle(KeyEvent event) { 
     if (event.getCode() == KeyCode.DOWN | event.getCode() == KeyCode.UP) { 
      stock.setCellFactory(column -> { 

       return new TableCell<VerreFX, Number>() { 
        @Override 
        protected void updateItem(Number item, boolean empty) { 
         super.updateItem(item, empty); 

         TableRow<VerreFX> currentRow = getTableRow(); 

         if (empty || item == null) { 
          setText(""); 
          setGraphic(null); 
          currentRow.setStyle(tableVerre.getStyle()); 
         } else { 
          setText(getItem().toString()); 
         } 

         if (!isEmpty()) { 
          if ((int) item == 0 && st.getVerresBOX()) { 
           currentRow.setStyle("-fx-background-color:lightcoral"); 
          } 
         } 
        } 
       }; 
      }); 
     } 
     System.err.println("Key Pressed : " + event.toString()); 
    } 
}); 
+0

Nützliche Bemerkungen in der Tat, Danke –

Verwandte Themen