2017-09-19 13 views
1

TableColumn<CustomObject, Boolean> tableColumnTwoチェックボックスがオンの場合にのみCustomObjectのフィールド値に基づいてTableColumn<CustomObject, String> tableColumnを無効にすることを検討しています。私は、誰もがこの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

に光を当てることができれば、非常に感謝通常、我々は細胞があることを期待、関連するコードスニペットがどのように以下updateItem 内のチェックボックスの状態を確認するにはわからないが内のテキストボックスを無効にすることができます基礎となるデータの変更について通知されるたびに更新されます。通知はアイテムのプロパティを変更することで、データによって発射されることを確実にするために、我々は、我々が興味を持っている性質に抽出してリストのようなものが必要になります。それに

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

の代わりにlistは、pretifiedプロパティが変更されるたびにtype updateのリストの変更を発生させます。

bug in fxのため残念ながら、それだけでは不十分です。基本アイテムからのタイプ更新のlistChangeを受け取ると、セルは更新されません。 (更新されたバグが修正されたら、使用しないでください。緊急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()); 
} 
関連する問題