当前位置: 首页 > 知识库问答 >
问题:

JavaFX,禁用TableView中的完整行

赵炯
2023-03-14

我在禁用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个答案

安泰平
2023-03-14

您可以尝试以下方法。该示例仅适用于最后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;
}
});

确保复选框作为单选按钮相互排斥,否则在启动时只设置最后一个有效的maxvalue(假设所有数据都存储在db中)

 类似资料:
  • 我需要我的使其所有列都可排序,但我不希望通过Shift单击列使其成为多列可排序。有什么办法可以防止这种情况发生吗?

  • 当我在JavaFX中生成一个表时,列太大了,我想在它出现在我的应用程序上时调整它们的大小,以减少它们。我在stackOverflow上阅读了那些有用的文章,但它们对我没有帮助:表视图中的javafx列自动调整大小;JavaFX TableCol的列调整大小以适应单元格内容。事实上,与主题不同,我的列中有列,但它不起作用。对于信息,这些列的反应相同,如果我们双击它们,它们会自动调整大小。我试图复制这

  • 问题内容: 我希望TableView的高度适应填充的行数,以使其从不显示任何空行。换句话说,TableView的高度不应超过最后填充的行。我该怎么做呢? 问题答案: 如果您希望此操作有效,则必须设置。 然后,您可以将的高度与表格中包含的项目大小乘以固定单元格大小绑定在一起。 演示: 注意:我乘以fixedCellSize *(数据大小+ 1.01)以包含标题行。

  • 我有一个TableView,在这个TableView中,有5列。其中一列只包含TableView中的行数,它只是对它们进行计数。以下行为是我想要实现的: 数字列应具有与其内容相适应的宽度 数字列不可缩放 其他列应可调整大小 当内容太长时,其他列可以并且应该截断它们的内容,以便它们适合TableView的区域,并且不可见水平滚动条 我有5个TableView列,我是这样创建的: 所以我的问题是:如何

  • 如何使用JavaFX TableView实现嵌套的行(而不是列)?还是在TableView中合并行?

  • 我在javaFX开发应用程序。我想在桌面上显示json的反应。我不知道怎么做 我的档案如下: 项目。fxml 项目控制器 我在中得到json响应,我想在表视图中显示它。 我不知道如何将json绑定到表视图。 我可以将json转换为数组。 但是,tableview的方法要求使用观测列表。 因此,任何建议和例子都将受到高度重视。