2017-09-19 9 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 속성이 변경 될 때마다 유형 업데이트 목록 변경을 시작합니다.

불행히도 bug in fx으로 충분하지 않습니다. 기본 항목에서 list 업데이트 유형을 수신하면 셀이 업데이트되지 않습니다. 더러운 방법 (읽기 : 버그가 고쳐지면 사용하지 마십시오. 비상용 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()); 
}