JavaFX,在TableView中禁用完整的Row

时间:2017-04-11 09:26:27

标签: javafx javafx-2 javafx-8

我在TableView中禁用行时遇到问题。我有一个包含三列的TableView。名称列,值列和复选框列。如果用户选中一个复选框,则应禁用所有行,其值与选中行中的值相同。我试图使用ReactFX2框架在禁用的属性和单元格之间创建绑定,但它没有用。有一个简单的方法来处理我的问题。这是我的代码:

trafficvolume.class

    package ExternalRessources;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableBooleanValue;

public class TrafficVolume {
    private  SimpleStringProperty name;
    private  SimpleStringProperty flightLVL;
    private  BooleanProperty check;
    private  BooleanProperty disabled;

    public TrafficVolume(String name, String flightLVL) 
    {
        this.name = new SimpleStringProperty(name);
        this.flightLVL = new SimpleStringProperty(flightLVL);
        this.check = new SimpleBooleanProperty(false);
        this.disabled = new SimpleBooleanProperty(false);
    }

    public String getName() {
        return name.get();
    }

    public String getFlightLVL() {
        return flightLVL.get();
    }

    public Boolean getCheck() {
        return check.get();
    }

    public BooleanProperty checkedProperty()
    {
        return check;
    }

    public void setCheck(Boolean checked)
    {
        this.check.set(checked);
    }

    public BooleanProperty disabledProperty()
    {
        return disabled;
    }

    public Boolean getDisabled() {
        return disabled.get();
    }




}

controller.class

    package GUI;

import java.io.IOException;
import java.util.ArrayList;

import javafx.beans.value.ObservableValue;
import ExternalRessources.TrafficVolume;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
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.layout.AnchorPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TVIDSelectionPanelController {


    @FXML
    private Button BACKBUTTON;
    @FXML
    private Button TEST;
    @FXML
    private MenuItem MENUITEMSETTINGS;
    @FXML
    private MenuBar MENUBAR;
    @FXML
    private GridPane GRIDPANETVID;
    @FXML
    private TableView<TrafficVolume> TABLETVID;
    @FXML
    private TableColumn<TrafficVolume, String> TABLECOLTVID;
    @FXML
    private TableColumn<TrafficVolume, String> TABLECOLFLIGHTLVL;
    @FXML
    private TableColumn<TrafficVolume, CheckBox> TABLECOLCHECKBOX;
    @FXML
    private AnchorPane TABLEPANE;

    private ExchangeController exchange;
    public ObservableList<TrafficVolume> list = FXCollections.observableArrayList();

    @FXML
    private void handleBACKBUTTON(ActionEvent event) throws IOException
    {         


    }

    public void init(ExchangeController ex)
    {
        this.exchange =ex;
    }

    @FXML   
    public void initalize() throws IOException
    {
        this.ChooseData();
    }

    @FXML
    private void ChooseData()
    {
        String EBG = exchange.getSelectedEBG();
        switch(EBG)
        {
            case "Central":
            {
                this.createTable(exchange.getCentralTVID());
                break;
            }
            case "West":
            {
                this.createTable(exchange.getWestTVID());
                break;
            }
            case "East":
            {
                this.createTable(exchange.getEastTVID());
                break;
            }
            case "North":
            {
                this.createTable(exchange.getNorthTVID());
                break;
            }
            case "South":
            {
                this.createTable(exchange.getSouthTVID());
                break;
            }
        }
    }


    private void createTable(ArrayList<ArrayList<String>> ListTVID)
    {
        for(int i=0;i<ListTVID.size();i++)
        {
            list.add(new TrafficVolume(ListTVID.get(i).get(0),ListTVID.get(i).get(1)));
        }
        TableColumn<TrafficVolume, String> TVIDs = new TableColumn<TrafficVolume, String>("TV-ID");
        TableColumn<TrafficVolume, String> FLVL = new TableColumn<TrafficVolume, String>("Flight Level");   
        TableColumn<TrafficVolume, Boolean> checkedCol = new TableColumn<TrafficVolume, Boolean>("Active");
        TABLETVID.setItems(list);
        TABLETVID.getColumns().addAll(TVIDs,FLVL,checkedCol);
        TVIDs.setCellValueFactory(new PropertyValueFactory<TrafficVolume, String>("name"));
        FLVL.setCellValueFactory(new PropertyValueFactory<TrafficVolume, String>("flightLVL"));
        checkedCol.setCellValueFactory(new PropertyValueFactory<TrafficVolume, Boolean>("check"));
        checkedCol.setCellFactory(CheckBoxTableCell.forTableColumn(checkedCol));
        checkedCol.setEditable(true);
        TABLETVID.setEditable(true);

        checkedCol.setCellFactory(CheckBoxTableCell.forTableColumn(new Callback<Integer, ObservableValue<Boolean>>()
        {
            @Override
            public ObservableValue<Boolean> call(Integer param)
            {

                return list.get(param).checkedProperty();
            }
        }));


        for (TrafficVolume trafficVolume : list) {
            trafficVolume.checkedProperty().addListener((obs, wasChecked,isNowChecked) -> {
                  System.out.println("Checked property for " + trafficVolume.getName() +
                            " changed from "+wasChecked + " to " + isNowChecked);

            });
        }

    }




    //Switch the Scene
    @FXML
    private void handleSettings(ActionEvent event) throws IOException
    {       
        exchange.setTVIDSelectionPanelScene(MENUBAR.getParent().getScene());
        exchange.setTVIDSelectionPanelStage((Stage) MENUBAR.getParent().getScene().getWindow());
        exchange.setLastScene(exchange.getTVIDSelectionPanelScene());
        exchange.setLastStage(exchange.getTVIDSelectionPanelStage());
        exchange.initalizeStageOptions(event, MENUBAR);  

    }


}

我想禁用所有与所选行相同的flightlvl的行。实施例

name   lvl       checked
FFM14  100-300   x
FFM15  100-250
FFM24  300-400
FFM34  400-500
应该禁用

ffm15,因为lvl是所选lvl的一部分。 谢谢你的帮助!!

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。该示例仅适用于最后3位数字,因此您需要对其进行修改以满足您的需求。

//将IntegerProperty添加为类字段:

private IntegerProperty maxvalue = new SimpleIntegerProperty(999);

//更改列类型

@FXML

private TableColumn < TrafficVolume, Boolean > TABLECOLCHECKBOX;

// initialize()方法标记错误。应该是:

@Override

public void initialize(URL url, ResourceBundle rb)

// GUI设计必须已存在于TVIDSelectionPanel.fxml文件中。无需重新声明并添加列

//现在是CellFactory部分:

TABLECOLFLIGHTLVL.setCellValueFactory(new PropertyValueFactory<>("flightLVL"));
 TABLECOLFLIGHTLVL.setCellFactory(new Callback < TableColumn < TrafficVolume, String >, TableCell < TrafficVolume, String >>() {

        @Override
            public TableCell<TrafficVolume, String> call(TableColumn<TrafficVolume, String> param) {

                TableCell<TrafficVolume, String> cell = new TableCell<TrafficVolume, String>(){

                    @Override
                    protected void updateItem(String item, boolean empty) {
                        if(item != null){
                        super.updateItem(item, empty); 
                        setText(empty ? null : item);
                        Integer myVal1 = Integer.valueOf(item.substring(4));
                        TableRow<TrafficVolume> tr = getTableRow();
                             if(tr.getItem().getCheck()){
                                 maxvalue.set(myVal1);
                             }
                tr.disableProperty().bind(Bindings.greaterThan(myVal1, maxvalue));

                 DoubleBinding bind2 = new DoubleBinding() {

                                {super.bind(maxvalue);}
                            @Override
                            protected double computeValue() {
                                //you can put other statements here, e.g to change Style
                                if(myVal1 > maxvalue.get()){
                                    return 0.5;
                                }else{
                                    return 1.0;
                                }
                            }
                        };

               tr.opacityProperty().bind(bind2);
                        }
                    }

                };

                return cell;
            }
        });


TABLECOLCHECKBOX.setCellValueFactory(new PropertyValueFactory<>("check"));
TABLECOLCHECKBOX.setCellFactory(new Callback<TableColumn<TrafficVolume, Boolean>, TableCell<TrafficVolume, Boolean>>() {
 @Override
 public TableCell<TrafficVolume, Boolean> call(TableColumn<TrafficVolume, Boolean> param) {
 TableCell<TrafficVolume, Boolean> cell = new CheckBoxTableCell<TrafficVolume, Boolean>(){
 @Override
  public void updateItem(Boolean item, boolean empty) {
  if(item != null ){
  super.updateItem(item, empty); 
  TableRow<TrafficVolume> tr = getTableRow();
  if(tr.getItem().checkedProperty().get()){
  tr.setStyle("-fx-background-color:lightgreen");
  }
  }
  }
 };

  cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
 @Override
 public void handle(MouseEvent event) {
 TrafficVolume tv = (TrafficVolume) cell.getTableRow().getItem();
 String lvl = tv.getFlightLVL();
 if(tv.getCheck()){
 maxvalue.set(Integer.valueOf(ordNr.substring(4)));
 cell.getTableRow().setStyle("-fx-background-color:lightgreen");
 }else{
 maxvalue.set(999);
 cell.getTableRow().setStyle("");    
}
}
});
 return cell;
}
});

确保复选框是互斥的,因为单选按钮在启动时只设置了最后一个有效的最大值(假设所有数据都存储在数据库中)