2017-03-26 63 views
1

我有TableView名爲tableVerre,我希望每行檢查條件(stock列值),並在滾動時對它們執行一些代碼,以便我寫入這段代碼,但它使程序消耗大量的CPU時間,我不熟悉Lambda表達式,所以是否有更簡單的方法來編寫它? :在TableView上處理ScrollEvent需要太多的CPU時間

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

爲什麼要替換滾動處理函數中的'cellFactory'?可能這些單元格甚至沒有重新創建,除非您調整表格的大小... – fabian

+0

我會在哪裏放置它?順便說一下,單元格重新創建時不用調整表格大小。 –

+0

如果您設置了新的單元工廠(AFAIK),單元格將被重新創建。如果您不會不斷更換單元工廠,那麼只需在用戶滾動時重用它們(將在現有單元上調用'updateItem(...)'方法)。顯然,簡單地調用'updateItem()'比重複更換所有單元要少得多。 –

回答

2

表視圖將重用的小區當用戶滾動,而當他們在爲新項目重用會自動調用updateItem的細胞。所以你應該只設置一次細胞工廠,然後讓表視圖負責完成它設計的工作。如果您使用的是FXML,您可以在initialize()方法中設置單元格工廠,否則可以在任何地方創建表格和列。

您的單元格實現不太正確:因爲單元格可能會被重複使用以任意顯示任意兩個不同的項目,所以您需要考慮所有可能的條件。在你的實現中,如果一個單元格顯示的項目爲item.intValue()==0,然後被重新使用以顯示一個項目爲item.intValue() != 0,那麼風格將不會被正確更新。

另請注意,您應通過致電intValue()Number「轉換」爲int

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()); 
      } 
     } 
    } 
}); 

您應該能夠完全移除滾動事件處理程序。

+0

是的我正在使用fxml並在initialize()中設置單元格工廠正是我的方法,但是一旦行更改樣式,顯示在該行中的每個單元格都將採用相同的樣式!沒有更新自己。 –

+0

這不僅僅是由於我指出的錯誤嗎? –

+0

這是你提到的,但我沒有那個錯誤!我曾經習慣了,我找到了一個解決方案(更新每個滾動事件上的單元格),它消耗了CPU時間,這是問題中的代碼,我發現了一種通過在滾動完成時更新單元來防止這種情況的方法。謝謝James –

1

首先,除了CPU時間外,您並未涵蓋所有滾動情況,因爲如果用戶使用向下/向上鍵或使用滾動條滾動,滾動事件將不會被觸發。所以你必須再添加兩個EventFilter,第一個將使用滾動條來處理滾動。

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"); 
          } 
         } 
        } 
       }; 
      }); 
     } 
    }); 

而第二個將使用鍵盤按鍵DOWN/UP處理滾動。

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

的確有用的評論,謝謝 –