本文介绍了当以多种方式更新时,我如何使用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控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!