2016-03-07 108 views
0

我有一個4行TableView和一個自定義單元格。第一個只是一個圖像,我想更新幾個圖像,一個字符串,一個換行字符串和一個第二個圖像作爲按鈕。JavaFX TableView單元格設置值更高

// image 
tcUrlStatus.setCellValueFactory(new ColumnImageFactory()); 
tcUrlStatus.setCellFactory(new ColumnCallback()); 

// one line string 
tcUrlName.setCellValueFactory(new ColumnNameFactory()); 
tcUrlName.setCellFactory(new ColumnCallback()); 

// two line string 
tcUrlDate.setCellValueFactory(new ColumnDateFactory()); 
tcUrlDate.setCellFactory(new ColumnCallback()); 

// image as a button 
tcDelete.setCellValueFactory(new ColumnDeleteFactory()); 
tcDelete.setCellFactory(new ColumnCallback()); 

這裏是定製單元

class ColumnCallback implements Callback<TableColumn<Quartet<Boolean, String, String, String>, Object>, TableCell<Quartet<Boolean, String, String, String>, Object>>{ 
    @Override 
    public TableCell<Quartet<Boolean, String, String, String>, Object> call(TableColumn<Quartet<Boolean, String, String, String>, Object> column) { 
     return new ColumnCell(); 
    } 
} 

class ColumnImageFactory implements Callback<TableColumn.CellDataFeatures<Quartet<Object, String, String, String>, String>, ObservableValue<Object>> { 
    @Override 
    public ObservableValue<Object> call(TableColumn.CellDataFeatures<Quartet<Object, String, String, String>, String> data) { 
     return new ReadOnlyObjectWrapper<>(data.getValue().getValue0()); 
    } 
} 

class ColumnNameFactory implements Callback<TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, String>, ObservableValue<String>> { 
    @Override 
    public ObservableValue<String> call(TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, String> data) { 
     return new ReadOnlyObjectWrapper<>(data.getValue().getValue1()); 
    } 
} 

class ColumnDateFactory implements Callback<TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, Object>, ObservableValue<Object>> { 
    @Override 
    public ObservableValue<Object> call(TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, Object> data) { 
     return new ReadOnlyObjectWrapper<>(data.getValue().getValue2()); 
    } 
} 

class ColumnDeleteFactory implements Callback<TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, Object>, ObservableValue<Object>> { 
    @Override 
    public ObservableValue<Object> call(TableColumn.CellDataFeatures<Quartet<Boolean, String, String, String>, Object> data) { 
     return new ReadOnlyObjectWrapper<>(data.getValue().getValue3()); 
    } 
} 

class ColumnCell extends TableCell<Quartet<Boolean, String, String, String>, Object> { 
    @Override 
    protected void updateItem(Object item, boolean empty) { 
     super.updateItem(item, empty); 

     if (item != null) { 
      if (item instanceof Boolean) { 
       setText(null); 
       Image image; 
       AnchorPane pane = new AnchorPane(); 

       if ((boolean) item) { 
        image = new Image(Main.class.getResourceAsStream("/hourglass.gif")); 
       } else { 
        image = new Image(Main.class.getResourceAsStream("/clean.gif")); 
       } 

       ImageView imageView = new ImageView(image); 
       imageView.setFitWidth(30); 
       imageView.setY(5); 
       imageView.setPreserveRatio(true); 
       imageView.setSmooth(true); 

       pane.getChildren().add(imageView); 

       setGraphic(pane); 
      }else { 
       if (item instanceof String) { 
        if (item.equals("delete")) { 
         AnchorPane pane = new AnchorPane(); 

         Image image = new Image(Main.class.getResourceAsStream("/cross.png")); 

         ImageView imageView = new ImageView(image); 
         imageView.setFitWidth(20); 
         imageView.setY(10); 
         imageView.setPreserveRatio(true); 
         imageView.setSmooth(true); 
         imageView.setCursor(Cursor.HAND); 

         pane.getChildren().add(imageView); 

         imageView.setOnMouseClicked((Event event) -> { 
          Quartet<Boolean, String, String, String> row = this.getTableView().getSelectionModel().getSelectedItem(); 

          Controller.localJson.remove(row.getValue1()); 
          this.getTableView().getItems().remove(row); 
         }); 

         setGraphic(pane); 
        } else { 
         HBox pane = new HBox(); 
         Label label = new Label(); 
         label.setText((String) item); 

         label.setTextAlignment(TextAlignment.CENTER); 

         if (((String) item).length() < 20) { 
          label.setWrapText(true); 
          label.setAlignment(Pos.CENTER); 
         } 

         pane.setPrefHeight(40); 
         label.setPrefHeight(40); 
         pane.getChildren().add(label); 

         setGraphic(pane); 
        } 

        setText(null); 
       } 
      } 
     } else { 
      setText(null); 
      setGraphic(null); 
     } 
    } 
} 

現在我想改變tcUrlStatus列/單元區域的圖像。我已經想出瞭如何獲取行或值,但我無法弄清楚如何設置值,或者更改圖像從true更改爲false或false。

GET行和值:

private int getTableRowIndex(String url){ // url is the second column 
    int counter = 0; 
    for (Object row:tvUrls.getItems()){ 
     if ((((Quartet) row).getValue1() == url)){ 
      return counter; 
     } 
     counter ++; 
    } 

    return -1; 
} 

int rowIndex = getTableRowIndex(url); 
Object item = tvUrls.getItems().get(rowIndex); 

回答

0

這將是最容易通過在Quartet類,例如使用JavaFX屬性來做到這一點假設用於value0豆類型是T

// TODO: Is using a readonly property really needed here ??? 
//  if not, use SimpleObjectProperty instead 
private final ReadOnlyObjectWrapper<T> value0 = new ReadOnlyObjectWrapper<>(); 

public T getValue0() { 
    return value0.get(); 
} 

// TODO: should the setter really be public ??? 
public void setValue0(T newValue) { 
    value0.set(newValue); 
} 

public ReadOnlyObjectProperty<T> value0Property() { 
    return value0.getReadOnlyProperty(); 
} 

,它允許您使用new PropertyValueFactory<>("value0"),而不是您的自定義單元格的值的工廠,而且,更重要的是,意味着TableView組件將在Quartet被變更通知實例。

這種方式,您可以簡單地使用

quartetInstance.setValue0(newValue0); 

,細胞就會得到更新。

使用PropertyValueFactory將有同樣的效果,用在這種情況下,以下cellValueFactory

class ColumnImageFactory implements Callback<TableColumn.CellDataFeatures<Quartet<Object, String, String, String>, String>, ObservableValue<Object>> { 
    @Override 
    public ObservableValue<Object> call(TableColumn.CellDataFeatures<Quartet<Object, String, String, String>, String> data) { 
     return data.getValue().value0Property(); 
    } 
} 

如果不能JavaFX的屬性添加到Quartet類,你所需要的變革之後更新TableView的一些其他的方式。 TableView.refresh()將工作(只要你使用JavaFX的版本> = 8u60),或在情況下寫an adapter您已經實現了在Quartet類其他方式觀察者彭定康...

+0

我沒有嘗試,但我用另一種解決方案解決了「問題」。我使用SimpleObjectProperty。這比使用Quartet類更乾淨。我會在一秒之內發佈它作爲我的解決方案:) –

+0

@ Mr.Tr33 Yup,通常你的項目包含屬性,而'cellValueFactory's返回其中一個屬性而不是創建一個新屬性;然後單元格顯示該屬性是否只讀。 – fabian

0

我從四方類chaning到SimpleObjectProperty解決它類。

初始化:

tcUrlStatus.setCellValueFactory(new PropertyValueFactory<ColumnCellValue, Boolean>("status")); 
tcUrlName.setCellValueFactory(new PropertyValueFactory<ColumnCellValue, String>("url")); 
tcUrlDate.setCellValueFactory(new PropertyValueFactory<ColumnCellValue, String>("date")); 
tcDelete.setCellValueFactory(new PropertyValueFactory<ColumnCellValue, Boolean>("delete")); 

tcUrlStatus.setCellFactory(new ColumnStatusCell()); 
tcUrlName.setCellFactory(new ColumnStringCell(false)); 
tcUrlDate.setCellFactory(new ColumnStringCell(true)); 
tcDelete.setCellFactory(new ColumnDeleteCell()); 

添加行:

tvUrls.getItems().add(new ColumnCellValue(true, url, date)); 

更新細胞:

ColumnCellValue statusRow = (ColumnCellValue) 
tvUrls.getItems().get(rowIndex); 

柱類:

public class ColumnCellValue{ 
    private final ObjectProperty status; 
    private final ObjectProperty url; 
    private final ObjectProperty date; 
    private final ObjectProperty delete = new SimpleObjectProperty<Boolean>(true); 

    ColumnCellValue(Boolean status, String url, String date) { 
     this.status = new SimpleObjectProperty<Boolean>(status); 
     this.url = new SimpleObjectProperty<String>(url); 
     this.date = new SimpleObjectProperty<String>(date); 
    } 

    public Object getDate() { 
     return date.get(); 
    } 

    public ObjectProperty dateProperty() { 
     return date; 
    } 

    public void setDate(Object date) { 
     this.date.set(date); 
    } 

    public Object getDelete() { 
     return delete.get(); 
    } 

    public ObjectProperty deleteProperty() { 
     return delete; 
    } 

    public void setDelete(Object delete) { 
     this.delete.set(delete); 
    } 

    public Object getStatus() { 
     return status.get(); 
    } 

    public ObjectProperty statusProperty() { 
     return status; 
    } 

    public void setStatus(Object status) { 
     this.status.set(status); 
    } 

    public Object getUrl() { 
     return url.get(); 
    } 

    public ObjectProperty urlProperty() { 
     return url; 
    } 

    public void setUrl(Object url) { 
     this.url.set(url); 
    } 
} 

class ColumnStatusCell implements Callback<TableColumn<Boolean, Boolean>,TableCell<Boolean, Boolean>>{ 
    @Override 
    public TableCell<Boolean, Boolean> call(TableColumn<Boolean, Boolean> param) { 
     AnchorPane pane = new AnchorPane(); 

     ImageView imageView = new ImageView(); 
     imageView.setFitWidth(30); 
     imageView.setY(5); 
     imageView.setPreserveRatio(true); 
     imageView.setSmooth(true); 

     TableCell<Boolean,Boolean> cell = new TableCell<Boolean,Boolean>(){ 
      public void updateItem(Boolean item, boolean empty) { 
       if(item!=null){ 
        Image image; 

        if (item) { 
         image = new Image(Main.class.getResourceAsStream("/hourglass.gif")); 
        } else { 
         image = new Image(Main.class.getResourceAsStream("/clean.gif")); 
        } 

        imageView.setImage(image); 
       } 
      } 
     }; 

     pane.getChildren().add(imageView); 
     cell.setGraphic(pane); 

     return cell; 
    } 
} 

class ColumnStringCell implements Callback<TableColumn<String, String>,TableCell<String, String>>{ 
    private boolean wrap = false; 

    ColumnStringCell(boolean wrap){ 
     this.wrap = wrap; 
    } 

    @Override 
    public TableCell<String, String> call(TableColumn<String, String> param) { 
     TableCell<String,String> cell = new TableCell<String,String>(){ 
      public void updateItem(String item, boolean empty) { 
       if(item!=null){ 
        Label label = new Label(); 
        label.setText(item); 
        label.setPrefHeight(40); 
        label.setTextAlignment(TextAlignment.CENTER); 

        label.setWrapText(wrap); 

        setGraphic(label); 
       } 
      } 
     }; 

     return cell; 
    } 
} 

class ColumnDeleteCell implements Callback<TableColumn<Boolean, Boolean>,TableCell<Boolean, Boolean>>{ 
    @Override 
    public TableCell<Boolean, Boolean> call(TableColumn<Boolean, Boolean> param) { 
     AnchorPane pane = new AnchorPane(); 

     ImageView imageView = new ImageView(); 
     imageView.setFitWidth(20); 
     imageView.setY(10); 
     imageView.setPreserveRatio(true); 
     imageView.setSmooth(true); 
     imageView.setCursor(Cursor.HAND); 

     TableCell<Boolean,Boolean> cell = new TableCell<Boolean,Boolean>(){ 
      public void updateItem(Boolean item, boolean empty) { 
       if (item != null) { 
        Image image = new Image(Main.class.getResourceAsStream("/cross.png")); 
        imageView.setImage(image); 
       } 
      } 
     }; 

     imageView.setOnMouseClicked((Event event) -> { 
      TableView table = (TableView) ((ImageView) event.getSource()).getParent().getParent().getParent().getParent().getParent().getParent().getParent(); 
      ColumnCellValue row = (ColumnCellValue) (table).getSelectionModel().getSelectedItem(); 

      Controller.localJson.remove(row.getUrl().toString()); 
      table.getItems().remove(row); 

      table.refresh(); 
     }); 

     pane.getChildren().add(imageView); 
     cell.setGraphic(pane); 

     return cell; 
    } 
} 
相關問題