2017-09-19 42 views
1

只有当TableColumn<CustomObject, Boolean> tableColumnTwo复选框被选中时,我才会根据CustomObject中的字段值禁用TableColumn<CustomObject, String> tableColumn。我可以禁用内部但不知道如何检查里面updateItem 复选框的状态的文本框下面是相关的代码片段,会非常感激,如果任何人都可以在这个JavaFX根据复选框状态禁用TableColumn

@FXML 
private TableColumn<CustomObject, Boolean> tableColumnTwo; 
@FXML 
private TableColumn<CustomObject, String> tableColumn; 

tableColumn.setCellFactory(
        new Callback<TableColumn<CustomObject, String>, TableCell<CustomObject, String>>() { 

         @Override 
         public TableCell<CustomObject, String> call(TableColumn<CustomObject, String> paramTableColumn) { 
          return new TextFieldTableCell<CustomObject, String>(new DefaultStringConverter()) { 
           @Override 
           public void updateItem(String s, boolean empty) { 
            super.updateItem(s, empty); 
            TableRow<CustomObject> currentRow = getTableRow(); 
            if(currentRow.getItem() != null && !empty) { 
             if (currentRow.getItem().getPetrified() == false) { // Need to check if checkbox is checked or not 
              setDisable(true); 
              setEditable(false); 
              this.setStyle("-fx-background-color: red"); 
             } else { 
              setDisable(false); 
              setEditable(true); 
                          setStyle(""); 
             } 
            } 
           } 
          }; 
         } 

        }); 
+0

https://stackoverflow.com/help/how-to-ask或者换句话说:请提供一个可运行的示例,说明你在做什么以及如何达不到目标:) – kleopatra

回答

1

您可以在复选框,选中它时会导致表刷新添加监听。

data = FXCollections.observableArrayList(new Callback<CustomObject, Observable[]>() { 

      @Override 
      public Observable[] call(CustomObject param) { 
       return new Observable[]{param.petrifiedProperty()}; 
      } 
    }); 


data.addListener(new ListChangeListener<CustomObject>() { 

     @Override 
     public void onChanged(ListChangeListener.Change<? extends CustomObject> c) { 
      while (c.next()) { 
       if (c.wasUpdated()) { 
        tableView.setItems(null); 
        tableView.layout(); 
        tableView.setItems(FXCollections.observableList(data)); 
       } 
      } 
     } 
    }); 

cellFactory将保持不变,当一个复选框被选中将被调用/听之任之。

1

通常阐明,我们预计细胞是每当他们被通知有关基础数据的变化时都会更新。要做出一定的通知由数据开火更改项目的属性,我们需要一个名单上,我们感兴趣的性质的提取,是这样的:

ObservableList<CustomObject> data = FXCollections.observableArrayList(
     c -> new Observable[] {c.petrifiedProperty()} 
); 

有了到位的只要推定的属性发生变化,列表就会触发类型更新的列表更改。

不幸的是,这还不够,因为bug in fx:当从基础项目接收到更新类型更新列表时,单元格不会更新。一个肮脏的方式(阅读:不要使用,一旦错误修复,它使用紧急API!)是安装一个监听器的项目,并在收到更新时致电table.refresh()

一个例子:

import java.util.logging.Logger; 

//import de.swingempire.fx.util.FXUtils; 
import javafx.application.Application; 
import javafx.beans.Observable; 
import javafx.collections.FXCollections; 
import javafx.collections.ListChangeListener; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableRow; 
import javafx.scene.control.TableView; 
import javafx.scene.control.cell.CheckBoxTableCell; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.control.cell.TextFieldTableCell; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import javafx.util.converter.DefaultStringConverter; 

/** 
* CheckBoxTableCell: update editable state of one column based of 
* the boolean in another column 
* https://stackoverflow.com/q/46290417/203657 
* 
* Bug in skins: cell not updated on listChange.wasUpdated 
* 
* reported as 
* https://bugs.openjdk.java.net/browse/JDK-8187665 
*/ 
@SuppressWarnings({ "rawtypes", "unchecked" }) 
public class TableViewUpdateBug extends Application { 


    /** 
    * TableCell that updates state based on another value in the row. 
    */ 
    public static class DisableTextFieldTableCel extends TextFieldTableCell { 

     public DisableTextFieldTableCel() { 
      super(new DefaultStringConverter()); 
     } 

     /** 
     * Just to see whether or not this is called on update notification 
     * from the items (it's not) 
     */ 
     @Override 
     public void updateIndex(int index) { 
      super.updateIndex(index); 
//   LOG.info("called? " + index); 
     } 

     /** 
     * Implemented to change background based on 
     * visible property of row item. 
     */ 
     @Override 
     public void updateItem(Object item, boolean empty) { 
      super.updateItem(item, empty); 
      TableRow<TableColumn> currentRow = getTableRow(); 
      boolean editable = false; 
      if (!empty && currentRow != null) { 
       TableColumn column = currentRow.getItem(); 
       if (column != null) { 
        editable = column.isVisible(); 
       } 
      } 
      if (!empty) { 
       setDisable(!editable); 
       setEditable(editable); 
       if (editable) { 
        this.setStyle("-fx-background-color: red"); 

       } else { 
        this.setStyle("-fx-background-color: green"); 
       } 
      } else { 
       setStyle("-fx-background-color: null"); 
      } 
     } 

    } 

    @Override 
    public void start(Stage primaryStage) { 
     // data: list of tableColumns with extractor on visible property 
     ObservableList<TableColumn> data = FXCollections.observableArrayList(
       c -> new Observable[] {c.visibleProperty()}); 

     data.addAll(new TableColumn("first"), new TableColumn("second")); 

     TableView<TableColumn> table = new TableView<>(data); 
     table.setEditable(true); 

     // hack-around: call refresh 
     data.addListener((ListChangeListener) c -> { 
      boolean wasUpdated = false; 
      boolean otherChange = false; 
      while(c.next()) { 
       if (c.wasUpdated()) { 
        wasUpdated = true; 
       } else { 
        otherChange = true; 
       } 

      } 
      if (wasUpdated && !otherChange) { 
       table.refresh(); 
      } 
      //FXUtils.prettyPrint(c); 
     }); 
     TableColumn<TableColumn, String> text = new TableColumn<>("Text"); 
     text.setCellFactory(c -> new DisableTextFieldTableCel()); 
     text.setCellValueFactory(new PropertyValueFactory<>("text")); 

     TableColumn<TableColumn, Boolean> visible = new TableColumn<>("Visible"); 
     visible.setCellValueFactory(new PropertyValueFactory<>("visible")); 
     visible.setCellFactory(CheckBoxTableCell.forTableColumn(visible)); 

     table.getColumns().addAll(text, visible); 

     BorderPane root = new BorderPane(table); 
     Scene scene = new Scene(root, 300, 150); 

     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @SuppressWarnings("unused") 
    private static final Logger LOG = Logger 
      .getLogger(TableViewUpdateBug.class.getName()); 
}