2012-11-20 83 views
0

我有一個表視圖,裏面有一列填充了TextField。TableView中的TextField不再滾動JavaFX

當我的數據很少,而且我的表格沒有滾動條時,所有的TextFields都出現了。

問題是,當我向下滾動我的表格然後再次上升時,一些TextFields丟失。

這裏是我充滿了文本字段列代碼:

purchaseQtyCol.setCellFactory(
       new Callback<TableColumn< TransactionModel, TextField>, TableCell< TransactionModel, TextField>>() { 
        @Override 
        public TableCell< TransactionModel, TextField> call(final TableColumn< TransactionModel, TextField> p) { 
         TableCell<TransactionModel, TextField> cell = new TableCell<TransactionModel, TextField>() { 


          @Override 
          public void updateItem(TextField item, boolean empty) { 
           super.updateItem(item, empty); 
           if (item != null) { 
            /** 
            * for(CheckBox cbb : canceledCB) { 
            * if(item.equals(cbb)) 
            * System.out.println("aa" + 
            * this.indexProperty().getValue() + " " + 
            * item.isSelected()); }* 
            */ 
            this.setGraphic(item); 
           } 

          } 

         }; 

         cell.setAlignment(Pos.CENTER); 
         return cell; 
        } 
       }); 

     purchaseQtyCol.setCellValueFactory(new Callback<CellDataFeatures<TransactionModel, TextField>, ObservableValue<TextField>>() { 
      @Override 
      public ObservableValue<TextField> call(final CellDataFeatures<TransactionModel, TextField> p) { 

        System.out.println("new textfield"); 
        final TextField qtyField = new TextField() { 
         @Override 
         public void replaceText(int start, int end, String text) { 

          if (text.matches("[0-9]") || text.equals("")) { 
           super.replaceText(start, end, text); 
           if (this.getText().isEmpty()) { 
            p.getValue().setPurchaseQty(0); 
            p.getValue().setTotalPrice(0); 
           } else { 
            p.getValue().setPurchaseQty(Integer.parseInt(this.getText())); 
            p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue()); 
           } 
           recountTotals(); 
          } 
         } 

         @Override 
         public void replaceSelection(String text) { 

          if (text.matches("[0-9]") || text.equals("")) { 
           super.replaceSelection(text); 
           if (this.getText().isEmpty()) { 
            p.getValue().setPurchaseQty(0); 
            p.getValue().setTotalPrice(0); 
           } else { 
            p.getValue().setPurchaseQty(Integer.parseInt(this.getText())); 
            p.getValue().setTotalPrice(p.getValue().purchaseQtyProperty().intValue() * p.getValue().basePriceProperty().intValue()); 
           } 
           recountTotals(); 
          } 
         } 
        }; 

        qtyField.setText("" + p.getValue().purchaseQtyProperty().getValue()); 
        qtyField.setAlignment(Pos.CENTER_RIGHT); 

       return new SimpleObjectProperty(qtyField); 
      } 
     }); 

我真的很感激,從你們的幫助。

問候,

Chrisma Andhika

回答

1

Chrisma!您面臨的問題是JavaFX關於更新tableview中的項目的一個着名問題。已經有一些解決方法,例如here。該解決方案由

tableview.getColumns().get(0).setVisible(false); 
tableview.getColumns().get(0).setVisible(true); 

引發的tableview的內部更新機制,但據我可以理解這種解決方案隻影響數據的改變,實現代碼如下的節點不風格。

我也用

@Override 
public void updateItem(Object item, boolean empty) 

我的執行,但它是不夠的,因爲當時有一個表和滾動條行太多,出現行的更新成爲一個絕對的混亂。

我需要的是使高亮所有可見行通過使用CSS來滿足一些標準。我實現了以下列方式:

Callback<TableView<Person>, TableRow<Person>> callBack = 
    new Callback<TableView<Person>, TableRow<Person>>() { 
     @Override 
     public TableRow<Person> call(TableView<Person> tableView) { 
       final TableRow<Person> row = new TableRow<Person>() { 
        @Override 
        public void updateItem(Person item, boolean empty) { 
          super.updateItem(item, empty); 
          if(!empty && item.getFirstName() == "John") { 
           getStyleClass().add("john"); 
          } 
        } 
       }; 
       row.visibleProperty().addListener(new ChangeListener() { 
        @Override 
        public void changed(ObservableValue observableValue, Object t, Object t1) { 
         Boolean oldValue = (Boolean)t; 
         Boolean newValue = (Boolean)t1; 
         if(oldValue && !newValue) { 
          row.getStyleClass().remove("john"); 
         } 
         if(!oldValue && newValue) { 
          if(row.getItem().getFirstName() == "John") 
           row.getStyleClass().add("john"); 
         } 
        } 
       }); 
       return row; 
     } 
}; 
tableview.setRowFactory(callBack); 

CSS文件應包含以下行:

.john { 
-fx-background-color: forestgreen; 
-fx-text-fill: white; 
-fx-border-style: solid; 
} 

當然,你可以選擇行的不同造型。

Person類應包含

public SimpleStringProperty firstNameProperty() { 
    return firstName; 
} 

正如你可以看到我添加偵聽到行的VisibleProperty,在這裏我控制每一行的CSS行爲。也許這個想法有助於在某些情況下解決tableview中的數據更新問題,而不僅僅是行式樣。

我還應該補充一點,我開始在上面的代碼中的public void changed方法中接收NullPointerException,儘管它不影響我的程序結果。

我希望它能幫助你,Chrisma!還有其他人!

0

我剛剛有複選框的問題。當我迅速滾動我的大桌時,他們隨機消失。我解決它只是通過刪除這一行我cellFactory:

@Override 
    public void updateItem(Boolean item, boolean empty) { 
     super.updateItem(item, empty); 
     if (empty) { 
      setText(null); 
      // setGraphic(null); (This line causes weird behaviour in scrolling, delete it) 
     } else { 
      checkBox.setSelected(item); 
     } 
    } 
0

嗯,我也有同樣的問題,顯然只繪製可見的文本字段,當我們用滾動不會出現,因爲只有繪製場景但不是textinputcontrol,所以我的解決方案是捕獲滾動事件,並且當您使用它來調整文本字段的大小並將其恢復爲原始大小時,因此迫使您重新繪製該對象,現在使用textinputcontrol顯示。現在強制重新繪製該對象,現在出現與textinputcontrol。

tableview.addEventFilter(ScrollEvent.ANY, new EventHandler<ScrollEvent>() { 
     @Override 
     public void handle(ScrollEvent scrollEvent) { 
      System.out.println("Scrolled."); 
      for(ObservableList<TextField> i:data) 
        { 
        for(TextField j: i) 
        { 
        j.setPrefSize(141, 31); 
        j.setPrefSize(140, 30); 
        } 
        } 
     } 
});