我有两个
ListView
控件,我需要能够在这些控件之间来回移动项目。移动是通过双击任一列表中的项目来完成的。
我还有一个搜索字段,可以从
Available
列表这就是我的麻烦所在。
我得到一个
UnsupportedOperationException' when trying to remove an item from the
列表视图
's items. My current method of filtering the list seems to convert the
列表视图
's list to an
AbstractList`无法编辑。
如何在保持基础列表可编辑的同时允许过滤?
主要类别
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FXML布局:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox fx:id="vboxMain" alignment="center" spacing="10" xmlns="http://javafx.com/javafx/9.0.1"
xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
</padding>
<children>
<HBox spacing="10.0">
<children>
<VBox fx:id="vboxAvailableSearchTags" spacing="5.0">
<children>
<Label style="-fx-font-weight: bold;" text="Available"/>
<TextField fx:id="txtSearch" prefWidth="100.0"/>
<ListView fx:id="lvAvailable" prefHeight="200.0" prefWidth="100.0"/>
</children>
</VBox>
<VBox prefHeight="200.0" prefWidth="100.0" spacing="5.0">
<children>
<Label style="-fx-font-weight: bold;" text="Seleted"/>
<ListView fx:id="lvSelected" prefHeight="200.0" prefWidth="100.0" VBox.vgrow="ALWAYS"/>
</children>
</VBox>
</children>
<padding>
<Insets top="10.0"/>
</padding>
</HBox>
</children>
</VBox>
控制器类别:
public class Controller {
@FXML
private TextField txtSearch;
@FXML
private ListView<String> lvAvailable;
@FXML
private ListView<String> lvSelected;
private ObservableList<String> availableList = FXCollections.observableArrayList();
private ObservableList<String> selectedList = FXCollections.observableArrayList();
@FXML
private void initialize() {
// List of available strings
availableList.addAll(
"One",
"Two",
"Three",
"Four",
"Five"
);
// Initialize the search function
// Wrap the list in a filtered list (initially showing all items)
FilteredList<String> filteredList = new FilteredList<>(availableList.sorted());
// Set the filter predicate whenever the filter changes
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
filteredList.setPredicate(availableItem -> {
// If filter text is empty, show all items
if (newValue == null || newValue.isEmpty()) {
return true;
}
// Compare the tag name and search tags with the filter text
String query = newValue.toLowerCase();
if (availableItem.toLowerCase().contains(query)) {
return true; // Query matches the available item
} else return availableItem.contains(query);
});
});
// Wrap the filtered list in a SortedList
SortedList<String> sortedList = new SortedList<>(filteredList);
lvAvailable.setItems(FXCollections.observableList(sortedList));
lvAvailable.setPlaceholder(new Label("No results"));
// Add the double-click listeners to move selected tags between the two lists
lvAvailable.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY) &&
mouseEvent.getClickCount() == 2) {
addItem(lvAvailable.getSelectionModel().getSelectedItem());
}
});
lvSelected.setOnMouseClicked(mouseEvent -> {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY) &&
mouseEvent.getClickCount() == 2) {
removeItem(lvSelected.getSelectionModel().getSelectedItem());
}
});
}
private void addItem(String item) {
// If the tag is not already in the Selected list...
if (item != null && !lvSelected.getItems().contains(item)) {
// Add the tag to the Selected list
lvSelected.getItems().add(item);
// Remove it from the available list
lvAvailable.getItems().remove(item);
}
}
private void removeItem(String item) {
// If the tag is not already in the Selected list...
if (item != null && !lvAvailable.getItems().contains(item)) {
// Add the tag to the Available list
lvAvailable.getItems().add(item);
// Remove it from the Selected list
lvSelected.getItems().remove(item);
}
}
}