Многоразовая функция поиска javafx
У меня есть программа, которая ищет наблюдаемый список и отображает все соответствующие случаи на столе. Поиск работает нормально, но я могу запустить эту часть программы только один раз. Кнопка поиска перестает отвечать после того, как программа вернулась к отображению полного наблюдаемого списка.
У меня есть отдельный класс (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);
});
}
});
Какие изменения мне нужно будет сделать, чтобы заново запустить процесс поиска? Или я должен превратить это в метод как часть моего класса поиска, который я могу использовать повторно?
Логика поиска ниже:
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;
}
}
1 ответ
Это не работает, потому что, когда вы очищаете поиск, действие на кнопке все еще установлено, чтобы очистить поиск...
Рассмотрим другую стратегию полностью. Вы можете использовать FilteredList
как список для таблицы. Затем просто переключите предикат в списке:
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...
}
}