JavaFX - 来自Textfield

时间:2017-04-28 14:17:57

标签: java javafx tableview filtering fxml

民间,

希望有人可以就以下事项向我提出建议: 我有一个名为packetTable的TableView。此tableView及其TableColumns将从名为Packet的类填充。这工作正常。

我现在添加了一个名为protoFilterField的TextField。我们的想法是,当文本输入到此TextField中时,TableView将根据用户输入进行过滤。

我将TextField OnAction方法设置为Initialize()方法。当我运行应用程序时,我的TableView最初完全填充,这是正确的。但是,如果我在我的新TextField中输入任何文本并点击返回,它会完全清除我的TableView。我试过输入'tcp'作为我的文字&这应该是有效的&将大量记录返回到我的过滤搜索中。

有人能找到我错的地方吗?任何建议将不胜感激。

public class PacketOverviewController {
    @FXML
    private TableView<Packet> packetTable;
    @FXML
    private TableColumn<Packet, String> StartTimeColumn;
    @FXML
    private TableColumn<Packet, Double> DurColumn;
    @FXML
    private TableColumn<Packet, String> ProtoColumn;
    @FXML
    private TableColumn<Packet, String> SrcAddrColumn;
    @FXML
    private TableColumn<Packet, String> SportColumn;
    @FXML
    private TableColumn<Packet, String> DirColumn;
    @FXML
    private TableColumn<Packet, String> DstAddrColumn;
    @FXML
    private TableColumn<Packet, String> DportColumn;
    @FXML
    private TableColumn<Packet, String> StateColumn;
    @FXML
    private TableColumn<Packet, String> sTosColumn;
    @FXML
    private TableColumn<Packet, String> dTosColumn;
    @FXML
    private TableColumn<Packet, String> SrcBytesColumn;
    @FXML
    private TableColumn<Packet, String> LabelColumn;

    @FXML
    private TextField SummaryCountField;

    @FXML
    private TextField protoFilterField;

    private ObservableList<Packet> data = FXCollections.observableArrayList();  //NEW TEST


    // Reference to the main application.
    private MainApp mainApp;

    /**
     * The constructor.
     * The constructor is called before the initialize() method.
     */
    public PacketOverviewController() {

    }

    @FXML
    private void initialize() {
        StartTimeColumn.setCellValueFactory(cellData -> cellData.getValue().StartTimeProperty());
        DurColumn.setCellValueFactory(cellData -> cellData.getValue().DurProperty().asObject());
        ProtoColumn.setCellValueFactory(cellData -> cellData.getValue().ProtoProperty());
        SrcAddrColumn.setCellValueFactory(cellData -> cellData.getValue().SrcAddrProperty());
        SportColumn.setCellValueFactory(cellData -> cellData.getValue().SportProperty());
        DirColumn.setCellValueFactory(cellData -> cellData.getValue().DirProperty());
        DstAddrColumn.setCellValueFactory(cellData -> cellData.getValue().DstAddrProperty());
        DportColumn.setCellValueFactory(cellData -> cellData.getValue().DportProperty());
        StateColumn.setCellValueFactory(cellData -> cellData.getValue().StateProperty());
        sTosColumn.setCellValueFactory(cellData -> cellData.getValue().sTosProperty());
        dTosColumn.setCellValueFactory(cellData -> cellData.getValue().dTosProperty());
        //SrcBytesColumn.setCellValueFactory(cellData -> cellData.getValue().SrcBytesProperty().asObject());
        LabelColumn.setCellValueFactory(cellData -> cellData.getValue().LabelProperty());


        //NEW FILTERED FUNCTIONALITY
        FilteredList<Packet> filteredData = new FilteredList<>(data, p -> true);    //NEW TEST
        //FILTER ON THE PROTOCOL FIELD
        protoFilterField.textProperty().addListener((observable, oldValue, newValue) -> {
            filteredData.setPredicate(packet -> {
                if (newValue == null || newValue.isEmpty()){
                    return true;
                }
                System.out.println("filter test 1");
                String lowerCaseFilter = newValue.toLowerCase();

                if (packet.getProto().toLowerCase().contains(lowerCaseFilter)){
                    return true;
                }
                return false;
            });
        });

        SortedList<Packet> sortedData = new SortedList<>(filteredData);
        sortedData.comparatorProperty().bind(packetTable.comparatorProperty());
        packetTable.setItems(sortedData);
        //END NEW FILTERED FUNCTIONALITY
    }

    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;

        packetTable.setItems(mainApp.getPacketData());

    }
}

2 个答案:

答案 0 :(得分:0)

需要data.setAll(mainApp.getPacketData())而不是我当前拥有的行。 (packetTable.setItems(mainApp.getPacketData()))

答案 1 :(得分:0)

你还没有在问题中发布足够的代码来回答这个问题,但是从评论和一些假设来看,我猜你正在加载FXML,代码看起来像

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/path/to/some/file.fxml"));
Parent root = loader.load();

PacketOverviewController controller = loader.getController();
controller.setMainApp(this);

然后问题是您将表的项设置为initialize()方法中的筛选列表,该方法作为load()进程的一部分进行调用。然后随后调用setMainApp(...),它实际上用主应用程序类中定义的列表替换那些项目(这不是一个好的设计,顺便说一下)。

您应该更新已过滤列表的基础列表:

public void setMainApp(MainApp mainApp) {
    this.mainApp = mainApp;

    // packetTable.setItems(mainApp.getPacketData());
    data.setAll(mainApp.getPacketData());
}