可重复使用的搜索函数javafx
Reusable search function javafx
我有一个程序可以搜索可观察列表并显示 table 上的所有匹配案例。搜索工作正常,但我只能 运行 程序的这一部分一次。程序返回显示完整的可观察列表后,搜索按钮停止响应。
我有一个单独的 class(Search.class) 来处理搜索可观察列表的所有逻辑。
搜索按钮和文本字段的代码如下:
partSearchBtn.setOnAction(searchPartEvent ->{
ObservableList<Part> searchPartDisplay = FXCollections.observableArrayList();
String searchQuery = partSearchField.getText();
try{
searchPartDisplay = Search.searchPartByNumber(Integer.parseInt(searchQuery));
partTable.setItems(searchPartDisplay);
partSearchBtn.setText("Clear");
partSearchBtn.setOnAction(clearSearchEvent ->{
partSearchBtn.setText("Search");
partTable.setItems(Inventory.partBin);
});
} catch(NumberFormatException hasText){
searchPartDisplay = Search.searchPartByText(searchQuery);
partTable.setItems(searchPartDisplay);
partSearchBtn.setText("Clear");
partSearchBtn.setOnAction(clearSearchEvent ->{
partSearchBtn.setText("Search");
partTable.setItems(Inventory.partBin);
});
}
});
我需要进行哪些更改才能重新运行搜索过程?
或者我应该把它变成一个方法作为我的搜索的一部分 class 我可以重用吗?
搜索逻辑如下:
package inventorymngmnt;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Search {
public static ObservableList<Part> searchPartByNumber(int inNum){
ObservableList<Part> searchBin = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseIn = (e.getClass() == Inhouse.class);
if(typeCaseIn == true){
Inhouse testIn = (Inhouse) e;
if(inNum == testIn.getMachineID())
searchBin.add(e);
}
if((inNum == e.getPartID()) || (inNum == e.getInstock()) || (inNum == e.getMax())
|| (inNum == e.getMin()) || ((double)inNum == e.getPrice())
|| (Integer.toString(inNum).contains(e.getName()))){
searchBin.add(e);
}
}
return searchBin;
}
public static ObservableList<Part> searchPartByText(String inString){
ObservableList<Part> searchBin = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseOut = (e.getClass() == Outsourced.class);
if(typeCaseOut == true){
Outsourced testOut = (Outsourced) e;
if(inString.equals(testOut.getCompanyName())){
searchBin.add(e);
}
}
if(inString.equals(e.getName())){
searchBin.add(e);
}
}
return searchBin;
}
public static ObservableList<Part> searchProdByNumber(int inNum){
ObservableList<Part> searchProd = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseIn = (e.getClass() == Inhouse.class);
if(typeCaseIn == true){
Inhouse testIn = (Inhouse) e;
if(inNum == testIn.getMachineID())
searchProd.add(e);
}
if((inNum == e.getPartID()) || (inNum == e.getInstock()) || (inNum == e.getMax())
|| (inNum == e.getMin()) || ((double)inNum == e.getPrice())
|| (Integer.toString(inNum).equals(e.getName()))){
searchProd.add(e);
}
}
return searchProd;
}
public static ObservableList<Part> searchProdByText(String inString){
ObservableList<Part> searchProd = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseOut = (e.getClass() == Outsourced.class);
if(typeCaseOut == true){
Outsourced testOut = (Outsourced) e;
if(inString.equals(testOut.getCompanyName())){
searchProd.add(e);
}
}
if(inString.equals(e.getName())){
searchProd.add(e);
}
}
return searchProd;
}
}
这不起作用,因为当您清除搜索时,按钮上的操作仍设置为清除搜索...
考虑完全不同的策略。您可以使用 FilteredList
作为 table 的列表。然后只需切换列表中的谓词:
Predicate<Part> noFilter = part -> true;
FilteredList<Part> filteredParts = new FilteredList<>(Inventory.partBin, noFilter);
partTable.setItems(filteredParts);
partSearchBtn.setOnAction(searchPartEvent -> {
if (filteredParts.getPredicate()==noFilter) {
String searchQuery = partSearchField.getText();
try {
int searchNumber = Integer.parseInt(searchQuery);
filteredParts.setPredicate(part -> Search.filterByNumber(part, searchNumber));
} catch (NumberFormatException exc) {
filteredParts.setPredicate(part -> Search.filterByText(part, searchQuery));
}
} else {
filteredParts.setPredicate(noFilter);
}
});
partSearchButton.textProperty().bind(Bindings
.when(filteredParts.predicateProperty().isEqualTo(noFilter))
.then("Search")
.otherwise("Clear"));
和
public class Search {
public static boolean filterByNumber(Part part, int number) {
if (part.getClass() == Inhouse.class) {
Inhouse testIn = (Inhouse) part ;
if (testIn.getMachineID() == number) {
return true ;
}
}
if((number == part.getPartID()) || (number == part.getInstock()) || (number == part.getMax())
|| ( number == part.getMin()) || ((double) number == part.getPrice())
|| (Integer.toString(number).contains(part.getName()))){
return true ;
}
return false ;
}
public static boolean filterByText(Part part, String text) {
//similarly...
}
}
我有一个程序可以搜索可观察列表并显示 table 上的所有匹配案例。搜索工作正常,但我只能 运行 程序的这一部分一次。程序返回显示完整的可观察列表后,搜索按钮停止响应。
我有一个单独的 class(Search.class) 来处理搜索可观察列表的所有逻辑。
搜索按钮和文本字段的代码如下:
partSearchBtn.setOnAction(searchPartEvent ->{
ObservableList<Part> searchPartDisplay = FXCollections.observableArrayList();
String searchQuery = partSearchField.getText();
try{
searchPartDisplay = Search.searchPartByNumber(Integer.parseInt(searchQuery));
partTable.setItems(searchPartDisplay);
partSearchBtn.setText("Clear");
partSearchBtn.setOnAction(clearSearchEvent ->{
partSearchBtn.setText("Search");
partTable.setItems(Inventory.partBin);
});
} catch(NumberFormatException hasText){
searchPartDisplay = Search.searchPartByText(searchQuery);
partTable.setItems(searchPartDisplay);
partSearchBtn.setText("Clear");
partSearchBtn.setOnAction(clearSearchEvent ->{
partSearchBtn.setText("Search");
partTable.setItems(Inventory.partBin);
});
}
});
我需要进行哪些更改才能重新运行搜索过程? 或者我应该把它变成一个方法作为我的搜索的一部分 class 我可以重用吗?
搜索逻辑如下:
package inventorymngmnt;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Search {
public static ObservableList<Part> searchPartByNumber(int inNum){
ObservableList<Part> searchBin = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseIn = (e.getClass() == Inhouse.class);
if(typeCaseIn == true){
Inhouse testIn = (Inhouse) e;
if(inNum == testIn.getMachineID())
searchBin.add(e);
}
if((inNum == e.getPartID()) || (inNum == e.getInstock()) || (inNum == e.getMax())
|| (inNum == e.getMin()) || ((double)inNum == e.getPrice())
|| (Integer.toString(inNum).contains(e.getName()))){
searchBin.add(e);
}
}
return searchBin;
}
public static ObservableList<Part> searchPartByText(String inString){
ObservableList<Part> searchBin = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseOut = (e.getClass() == Outsourced.class);
if(typeCaseOut == true){
Outsourced testOut = (Outsourced) e;
if(inString.equals(testOut.getCompanyName())){
searchBin.add(e);
}
}
if(inString.equals(e.getName())){
searchBin.add(e);
}
}
return searchBin;
}
public static ObservableList<Part> searchProdByNumber(int inNum){
ObservableList<Part> searchProd = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseIn = (e.getClass() == Inhouse.class);
if(typeCaseIn == true){
Inhouse testIn = (Inhouse) e;
if(inNum == testIn.getMachineID())
searchProd.add(e);
}
if((inNum == e.getPartID()) || (inNum == e.getInstock()) || (inNum == e.getMax())
|| (inNum == e.getMin()) || ((double)inNum == e.getPrice())
|| (Integer.toString(inNum).equals(e.getName()))){
searchProd.add(e);
}
}
return searchProd;
}
public static ObservableList<Part> searchProdByText(String inString){
ObservableList<Part> searchProd = FXCollections.observableArrayList();
for(Part e: Inventory.partBin){
boolean typeCaseOut = (e.getClass() == Outsourced.class);
if(typeCaseOut == true){
Outsourced testOut = (Outsourced) e;
if(inString.equals(testOut.getCompanyName())){
searchProd.add(e);
}
}
if(inString.equals(e.getName())){
searchProd.add(e);
}
}
return searchProd;
}
}
这不起作用,因为当您清除搜索时,按钮上的操作仍设置为清除搜索...
考虑完全不同的策略。您可以使用 FilteredList
作为 table 的列表。然后只需切换列表中的谓词:
Predicate<Part> noFilter = part -> true;
FilteredList<Part> filteredParts = new FilteredList<>(Inventory.partBin, noFilter);
partTable.setItems(filteredParts);
partSearchBtn.setOnAction(searchPartEvent -> {
if (filteredParts.getPredicate()==noFilter) {
String searchQuery = partSearchField.getText();
try {
int searchNumber = Integer.parseInt(searchQuery);
filteredParts.setPredicate(part -> Search.filterByNumber(part, searchNumber));
} catch (NumberFormatException exc) {
filteredParts.setPredicate(part -> Search.filterByText(part, searchQuery));
}
} else {
filteredParts.setPredicate(noFilter);
}
});
partSearchButton.textProperty().bind(Bindings
.when(filteredParts.predicateProperty().isEqualTo(noFilter))
.then("Search")
.otherwise("Clear"));
和
public class Search {
public static boolean filterByNumber(Part part, int number) {
if (part.getClass() == Inhouse.class) {
Inhouse testIn = (Inhouse) part ;
if (testIn.getMachineID() == number) {
return true ;
}
}
if((number == part.getPartID()) || (number == part.getInstock()) || (number == part.getMax())
|| ( number == part.getMin()) || ((double) number == part.getPrice())
|| (Integer.toString(number).contains(part.getName()))){
return true ;
}
return false ;
}
public static boolean filterByText(Part part, String text) {
//similarly...
}
}