当以多种方式更新时,我如何使用MVC模型动态过滤JavaFX中的Listview控件? [英] How could I dynamically filter a listview control in javafx using the MVC model while is updated in more than one way?

查看:21
本文介绍了当以多种方式更新时,我如何使用MVC模型动态过滤JavaFX中的Listview控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了3个文件:View.fxml、Main和控制器。

我找到了一种方法,可以在剪贴板更新时(复制字符串时)使用剪贴板中存储的字符串更新Listview控件。

我一直无法实现的是,我还希望在用户更新文本字段时更新/筛选相同的列表。我不确定如何设置观察列表、谓词或在哪个文件、主文件或控制器文件中。

我添加代码:

Main



import Controller.Controller01;
import Model.Clip;
import Model.ClipboardListener;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.ObjectExpression;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.input.Clipboard;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.concurrent.Task;

import java.util.stream.IntStream;

public class Main extends Application  {


    @Override
    public void start(Stage primaryStage) throws Exception {

        FXMLLoader loader =new FXMLLoader();
        loader.setLocation(Main.class.getResource("/View/View01.fxml"));
        Parent root = loader.load();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);

        primaryStage.setX(200);
        primaryStage.setY(500);
        Rectangle2D bounds = Screen.getPrimary().getVisualBounds();
        double x = bounds.getMinX() + (bounds.getWidth() - scene.getWidth()) * 0.2;
        double y = bounds.getMinY() + (bounds.getHeight() - scene.getHeight()) * 0.55;
        primaryStage.setX(x);
        primaryStage.setY(y);


// longrunning operation runs on different thread
        Thread thread = new Thread(new Runnable() {
            String oldString = "";
            @Override
            public void run() {

                System.out.println("pulse in run 1 ");
                System.out.println("crrent thread: " + Thread.currentThread().getName());


                Runnable updater = new Runnable() {


                    @Override
                    public void run() {
                        //updateview();

                    }   //    run   ends ---------------------------------------------------

                };    //    updater   ends ---------------------------------------------------






            }

        });   //  thread runnable ends -------------------------------------------------------
        // don't let thread prevent JVM shutdown
        thread.setDaemon(true);
        thread.start();





// --------------------------------------------------------------------------------------------------------------------
        //  in main, clipboard listener, I'm unsure how to update the listivew here if the textfield changes
// --------------------------------------------------------------------------------------------------------------------

        final Clipboard systemClipboard = Clipboard.getSystemClipboard();
        new com.sun.glass.ui.ClipboardAssistance(com.sun.glass.ui.Clipboard.SYSTEM) {
            @Override
            public void contentChanged() {

                System.out.print("System clipboard content changed: ");
                if ( systemClipboard.hasImage() ) {
                    System.out.println("image");
                } else if ( systemClipboard.hasString() ) {
                    System.out.println("string");
                    //System.out.println(Clipboard.getSystemClipboard().getString());
                    System.out.println("current thread: " + Thread.currentThread().getName());


                   // controller.mylistviewvar.setItems(data);


                    Controller.Controller01 controller = loader.getController();           // works1
                    String fromclipboard = Clipboard.getSystemClipboard().getString();


                    ObservableList<String> items = FXCollections.observableArrayList();
                    

                    //controller.mylistviewvar.getItems().add(0,fromclipboard);                  // works1


                } else if ( systemClipboard.hasFiles() ) {
                    System.out.println("files");
                }
            }
        };
// --------------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------------


        primaryStage.show();
        System.out.println("crrent thread: " + Thread.currentThread().getName());




    }  // start stage ends --------------------------------------------

    

//  Mythread01   ends -----------------------------------




    public final Controller01 controller = new Controller01();

} // Main ends

控制器

package Controller;

import Model.Clip;
import Model.ClipboardListener;
import com.sun.tools.javac.Main;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.ToggleButton;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.*;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.input.Clipboard;
import javafx.stage.Stage;
import javafx.scene.control.TextField;

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

public class Controller01 implements Initializable {


    @FXML
    private Button myButton01;

    @FXML
    public ListView<String> mylistviewvar;

    public void setMylistviewvar(String listviewvar) {
        mylistviewvar.getItems().add(listviewvar);
    }

    @FXML
    void myButton01myEventClicked(MouseEvent event) {
        System.out.println("hi there !");


        // to put string INTO clipboard
        Clipboard clipboard = Clipboard.getSystemClipboard();
        ClipboardContent content = new ClipboardContent();
        content.putString("Some text");
        clipboard.setContent(content);
        // to copy from clipboard
        String fromclipboardstr = Clipboard.getSystemClipboard().getString();
        System.out.println(fromclipboardstr);


        //  ---------   alert dialogs
//        Alert alert = new Alert(Alert.AlertType.INFORMATION);
//        alert.setTitle("Information Dialog");
//        //alert.setHeaderText("Look, an Information Dialog");
//        alert.setContentText("I have a great message for you!");
//        alert.showAndWait();

//        Alert alert = new Alert(Alert.AlertType.INFORMATION);
//        alert.setTitle("Information Dialog");
//        alert.setHeaderText(null);
//        alert.setContentText("I have a great message for you!");
//        alert.showAndWait();




    }  // button click ends
    @FXML
    private ToggleButton myToggleBut;


// using this template methods in main can be accessed
//    @FXML protected void handleSubmitButtonRegister() throws IOException{
//        //
//        //Here I want to invoke gotoRegister
//        FXMLExampleMVC.getInstance().gotoRegister();
//    }

    @FXML
    private AnchorPane myAnchorPane;


    @FXML
    void myToggleButEventSB(MouseEvent event) {



        if (myToggleBut.isSelected()) {
            System.out.println("is ON");
            Stage stage = (Stage) myAnchorPane.getScene().getWindow();
            stage.setAlwaysOnTop(true);
        }else {
            System.out.println("is OFF");
            Stage stage = (Stage) myAnchorPane.getScene().getWindow();
            stage.setAlwaysOnTop(false);
        }
    }


//    public void testingcopyaction(Scene scene){
//
//        ObservableList<Clip> list = FXCollections.observableArrayList();
//        scene.getAccelerators().put(copyCombination, () -> {
//            if (!list.isEmpty()) {
//                ClipboardContent content = new ClipboardContent();
//                content.putString(list.getSelectedItem().getClip());
//                // original:
//                // content.putString(table.getSelectionModel().getSelectedItem().getClip());
//                Clipboard.getSystemClipboard().setContent(content);
//            }
//        });
//
//
//    }
//
//    private static final KeyCodeCombination copyCombination = new KeyCodeCombination(KeyCode.C, KeyCombination.CONTROL_ANY);
//
//    private static final KeyCodeCombination pasteCombination = new KeyCodeCombination(KeyCode.V, KeyCodeCombination.CONTROL_ANY);


    // ------------------------- learned that copying from selected cell/item



//    public void updateview(){
//        ObservableList<Clip> list = FXCollections.observableArrayList();
//        ListView<String> mylistviewvar = new ListView<>(list);
//        String fromclipboard = Clipboard.getSystemClipboard().getString();
//
//
//
//        mylistviewvar.getItems().add(fromclipboard);
//
//
//
//    }


    @FXML
    private TextField searchFieldvar;

    public TextField getSearchFieldvar() {
        return searchFieldvar;
    }

    public void setSearchFieldvar(TextField searchFieldvar) {
        this.searchFieldvar = searchFieldvar;
    }

    @FXML
    void myonKeyTyped(KeyEvent event) {


     System.out.println("input changed");









//        ObservableList<String> list = FXCollections.observableArrayList(mylistviewvar.getItems());
//
//        FilteredList<String> filteredList = new FilteredList<String>(list);
//        filteredList.setPredicate((e) -> true);
//
//        // ListView<String> listView = new ListView<>(filteredList);
//
//
//
//        //TextField textField = new TextField();
//        searchFieldvar.textProperty().addListener((e) -> filteredList.setPredicate((v) -> (searchFieldvar.getText() == null || searchFieldvar.getText().length() == 0 || v.startsWith(searchFieldvar.getText()))));
//
//        mylistviewvar.setItems(filteredList);












//        FilteredList<String> filteredData = new FilteredList<>(mylistviewvar.getItems(), s -> true);
//
//        String filter = searchFieldvar.getText();
//
//      // System.out.println("changed");
//       if(filter == null || filter.length() == 0) {
//           filteredData.setPredicate(s -> true);
//       }
//       else {
//           filteredData.setPredicate(s -> s.contains(filter));
//       }

    }








    public void applyClipboardPolling() {
        ObservableList<Clip> list = FXCollections.observableArrayList();
        ListView<Clip> mylistviewvar = new ListView<>(list);

        final Clipboard clipboard = Clipboard.getSystemClipboard();
        new com.sun.glass.ui.ClipboardAssistance(com.sun.glass.ui.Clipboard.SYSTEM) {
            @Override
            public void contentChanged() {
                // called every time system clipboard is changed
                // if the clipboard has a new String, add it to the TableView
                if (clipboard.hasString()) {

                    String toBeCopied = clipboard.getString();
                    // If the user hasn't selected anything in the table, we can safely add item
                    //
                    // If the user has selected something, and the selected clip differs from
                    // the String being copied, then we can add it.

                    // ObservableList<String> listview = FXCollections.observableArrayList("john","jane");
                    Clip clip = new Clip();
                    clip.setClip(clipboard.getString());
                    mylistviewvar.getItems().add(clip);


                    if (mylistviewvar.getSelectionModel().isEmpty() || !mylistviewvar.getSelectionModel().getSelectedItem().getClip().equals(toBeCopied)) {
                        Clip clip1 = new Clip();
                        clip1.setClip(clipboard.getString());
                        Clip lastCopied = (mylistviewvar.getItems().size() > 1) ? mylistviewvar.getItems().get(mylistviewvar.getItems().size() - 1) : null;
                        if (lastCopied != null && lastCopied.getClip().equals(toBeCopied)) {
                            // sometimes the contentChanged() method is called without the
                            // content actually having changed, don't add in this case
                            return;
                        }
                        mylistviewvar.getItems().add(clip1);
                    }
                }
            }
        };
    }




   @Override
   public void initialize(URL url, ResourceBundle resourceBundle) {

//       ClipboardListener listener = new ClipboardListener();
//       listener.setEntryListener(this);
//       listener.start();


      // FilteredList<String> filteredList = new FilteredList<String>(mylistviewvar.getItems());
      // filteredList.setPredicate((e) -> true);


       ObservableList<String> data = FXCollections.observableArrayList(mylistviewvar.getItems());

       FilteredList<String> filteredData = new FilteredList<>(data, s -> true);


       searchFieldvar.textProperty().addListener(obs->{

           String filter = searchFieldvar.getText();
           if(filter == null || filter.length() == 0) {
               filteredData.setPredicate(s -> true);
           }
           else {
               filteredData.setPredicate(s -> s.contains(filter));
           }
       });


















   }  //  initializable ends -------------------------------




//    @Override
//    public void onCopy(String data) {
//        mylistviewvar.getItems().add(0,  data);
//    }





} // Controller01 ends

View.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ToggleButton?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane fx:id="myAnchorPane" prefHeight="374.0" prefWidth="1188.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller.Controller01">
   <children>
      <Button fx:id="myButton01" layoutX="42.0" layoutY="28.0" mnemonicParsing="false" onMouseClicked="#myButton01myEventClicked" text="Get clipboard type" />
      <ListView fx:id="mylistviewvar" layoutX="14.0" layoutY="133.0" prefHeight="229.0" prefWidth="561.0" />
      <TextField fx:id="searchFieldvar" layoutX="157.0" layoutY="89.0" onKeyTyped="#myonKeyTyped" prefHeight="37.0" prefWidth="297.0" />
      <TextArea layoutX="583.0" layoutY="133.0" prefHeight="229.0" prefWidth="591.0" />
      <ToggleButton fx:id="myToggleBut" layoutX="526.0" layoutY="16.0" mnemonicParsing="false" onMouseClicked="#myToggleButEventSB" prefHeight="25.0" prefWidth="98.0" text="On Top" />
   </children>
</AnchorPane>

推荐答案

以下是如何使用FilteredList<E>筛选ListView显示的内容的示例:

List<String> names = Arrays.asList("John", "Winston", "Viggo Tarasov", "Cassian", "Bowery King", "Sofia");

// You can add items from other sources to this list
ObservableList<String> sourceList = FXCollections.observableArrayList(names);

// Create a FilteredList with your source list
FilteredList<String> filteredNames = new FilteredList<>(sourceList);

// Bind the predicate property of the filtered list to the text field.
// The following line tells the list to update the filtered items when the text field's text changes
filteredNames.predicateProperty().bind(Bindings.createObjectBinding(() -> name -> name.contains(searchField.getText()), searchField.textProperty()));

// Use the filtered list in the list view
namesListView.setItems(filteredNames);

这篇关于当以多种方式更新时,我如何使用MVC模型动态过滤JavaFX中的Listview控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆