我在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的一部分。 谢谢你的帮助!!
答案 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;
}
});
确保复选框是互斥的,因为单选按钮在启动时只设置了最后一个有效的最大值(假设所有数据都存储在数据库中)