Autocomplete unmatched results - java

I am trying to do autocomplete when I type in characters in ice:selectInputText
Issue I am facing is when I type in characters it brings even names which is not matching with the characters I type.
See the below screen shot for reference.
Ideally autocomplete should display only the first row from the result, however it displays rows which are not matching my typed characters.
Only Abell Maryland 20606 should display.
This is the code which is using for the comparison, how can I modify this to suit to my requirement which is to display only those results which is matching to what I type.
public int compare(Object o1, Object o2) {
if (o1 instanceof SelectItem) {
s1 = ((SelectItem) o1).getLabel();
} else {
s1 = o1.toString();
}
if (o2 instanceof SelectItem) {
s2 = ((SelectItem) o2).getLabel();
} else {
s2 = o2.toString();
}
return s1.compareToIgnoreCase(s2);
}
};
I am following this tutorial from Icefaces
http://wiki.icefaces.org/display/ICE/Auto-Complete
Update
My code in autocomplete.jspx
<ice:selectInputText rows="10" width="300"
listVar="emp"
valueChangeListener="#{mybean.updateList}"
listValue="#{mybean.list}">
<f:facet name="selectInputText">
<ice:panelGrid columns="3" columnClasses="empNameCol">
<ice:outputText value="#{emp.empName}"/>
</ice:panelGrid>
method updateList
public void updateList(ValueChangeEvent event) {
setMatches(event);
if (event.getComponent() instanceof SelectInputText) {
SelectInputText autoComplete = (SelectInputText)event.getComponent();
if (autoComplete.getSelectedItem() != null) {
bean = (Bean)autoComplete.getSelectedItem().getValue();
}
else {
Bean tempCity = getMatch(autoComplete.getValue().toString());
if (tempCity != null) {
bean = tempCity;
}
}
}
}
Method setMatches
private void setMatches(ValueChangeEvent event) {
Object searchWord = event.getNewValue();
int maxMatches = ((SelectInputText)event.getComponent()).getRows();
List matchList = new ArrayList(maxMatches);
try {
int insert =
Collections.binarySearch(dictionary, searchWord, AutoCompleteDictionary.LABEL_COMPARATOR);
if (insert < 0) {
insert = Math.abs(insert) - 1;
}
for (int i = 0; i < maxMatches; i++) {
if ((insert + i) >= dictionary.size() || i >= maxMatches) {
break;
}
matchList.add(dictionary.get(insert + i));
}
} catch (Throwable e) {
e.printStackTrace();
logger.error("Erorr finding autocomplete matches" + e.getMessage());
}
if (this.matchesList != null) {
this.matchesList.clear();
this.matchesList = null;
}
this.matchesList = matchList;
}
Update 2
Modified setMatches method
private void setMatches(ValueChangeEvent event) {
Object searchWord = event.getNewValue();
int maxMatches = ((SelectInputText) event.getComponent()).getRows();
List matchList = new ArrayList(maxMatches);
try {
for(int i = 0; i < dictionary.size(); i++) {
SelectItem s = (SelectItem)dictionary.get(i);
if(s.getLabel().startsWith(searchWord.toString())) {
matchList.add(s);
if(matchList.size() == maxMatches)
break;
}
}
} catch (Throwable e) {
e.printStackTrace();
logger.error("Erorr finding autocomplete matches" + e.getMessage());
}
if (this.matchesList != null) {
this.matchesList.clear();
this.matchesList = null;
}
this.matchesList = matchList;
}

You have to update the list of SelectItems. Instead of just odering the list you have to filter the list (or creating a new one which only contains the matches). The next time the autocomplete-list renders it will evaluate the bound list again.
The tutorial of icefaces has some sources attached (bottom). Take a look at AutoCompleteBean . The method updateList(ValueChangeEvent e) calls setMatches(e). Within this method the list is assigned with a new one.
// assign new matchList
if (this.matchesList != null) {
this.matchesList.clear();
this.matchesList = null;
}
this.matchesList = matchList;
This causes the ui component to show only items which match the input.
To sum it up: ice:selectInputList will always show the items contained in its list, so reduce the items in the list to show the relevant ones only.
Regards
Update
private void setMatches(ValueChangeEvent event) {
Object searchWord = event.getNewValue();
int maxMatches = ((SelectInputText)event.getComponent()).getRows();
List matchList = new ArrayList(maxMatches);
try {
for(int i = 0; i < dictionary.size(); i++) {
SelectItem s = dictionary.get(i);
if(s.getLabel().startsWith(searchWord)) {
matchList.add(s);
if(matchList.size() == maxMatches)
break;
}
}
} catch (Throwable e) {
e.printStackTrace();
logger.error("Erorr finding autocomplete matches" + e.getMessage());
}
if (this.matchesList != null) {
this.matchesList.clear();
this.matchesList = null;
}
this.matchesList = matchList;
}
// note: not optimized, just to explain how to do.
Update 2 (short version)
/**
* Fills the suggestionList with the given luceneResult.
*
* #param suggestionList The list to fill.
* #param luceneResult The previously computed luceneResult.
*/
private static void fillLookupSuggestionList(final List<SelectItem> suggestionList,
LuceneResult luceneResult)
{
suggestionList.clear();
String searchQuery = luceneResult.getLuceneResultConfig().getSearchQuery();
if (luceneResult.getResultSize() <= 0)
{
suggestionList.add(new SelectItem(null, BundleHelper.i18n(LuceneLookupController.BUNDLE,
LuceneLookupController.NO_ITEM_FOUND)));
}
else
{
List<LuceneResultEntry> results = luceneResult.getResult();
for (LuceneResultEntry entry : results)
{
suggestionList.add(new SelectItem(entry.getMetaInfo(),
entry.getInfo().getDescription()));
}
}
}

Related

How to display and add tasks to file according to priorities using Java

I need to display/list the contents of a txt file in the ascending order of priority. So, should I need to take a seperate input for priority of task or can I splice the input line?
private static void show() {
String[] items = getData("task.txt");
if (items.length == 0) {
System.out.println("There are no pending tasks!");
} else {
for (int i = items.length - 1; i >=0; i--) {
System.out.printf("[%d] %s\n", i + 1, items[i]);
}
}
My getData looks like this:
private static String[] getData(String file) {
ArrayList<String> dataList = new ArrayList<>();
Scanner s=null;
try {
s = new Scanner(new FileReader(file));
while (s.hasNextLine()){
dataList.add(s.nextLine());
}s.close();
} catch (Exception e) {
System.out.println("Problem to open \"task.txt\".");
} finally {
if (s != null) {
try {
s.close();
} catch (Exception e) {
}
}
}
String[] items = new String[dataList.size()];
for (int i = 0; i < items.length; i++) {
items[i] = dataList.get(i);
}
return items;
}
Input:
10 the thing i need to do
5 water the plants
11 clean house
Output: 5 water the plants
10 the thing i need to do
11 clean house
You can just sort the ArrayList datalist:
(I am assuming that the "priority item" format is already in it)
dataList.sort((o1, o2) -> {
Integer priority1 = Integer.parseInt(o1.split(" ")[0]);
Integer priority2 = Integer.parseInt(o2.split(" ")[0]);
return priority1.compareTo(priority2);
});
Put this right after the try-catch-finally-block.

How to remove code duplication in this java code

Using the same for-each loop inside 2 different method, is there any way to reduce code duplication here?
1st code
for (AjaxControlBean controlBean : requestData.getControls()) {
if (StringUtils.isAnyBlank(controlBean.getId(), controlBean.getName()) || "repeat".equalsIgnoreCase(controlBean.getType()))
{
continue;
}
FormInstanceControl control = formInstance.getControl(controlBean.getId());
if (control == null) {
control = new FormInstanceControl();
control.setFormInstance(formInstance);
control.setControlId(controlBean.getId());
formInstance.putControl(control);
}
if (controlBean.getValues() != null) {
if (control.getData() != null)
control.getData().clear();
else
control.setData(new ArrayList<FormInstanceData>());
for (String value : controlBean.getValues()) {
FormInstanceData data = new FormInstanceData();
data.setControl(control);
data.setType(FormInstanceData.TYPE_TEXT);
data.setText(value);
control.getData().add(data);
}
}
}
2nd code
for (AjaxControlBean controlBean : requestData.getControls()) {
if (StringUtils.isAnyBlank(controlBean.getId(), controlBean.getName()) || "repeat".equalsIgnoreCase(controlBean.getType())) {
continue;
}
FormInstanceControl control = formInstance.getControl(controlBean.getId());
if (control == null) {
control = new FormInstanceControl();
control.setFormInstance(formInstance);
control.setControlId(controlBean.getId());
formInstance.putControl(control);
}
if (controlBean.getValues() != null) {
if (control.getData() != null) {
control.getData().clear();
}
else
{
control.setData(new ArrayList<FormInstanceData>());
}
int i = 0;
for (String value : controlBean.getValues()) {
FormInstanceData data = new FormInstanceData();
data.setControl(control);
data.setType(FormInstanceData.TYPE_TEXT);
data.setText(value);
data.setIdx(i++);
control.getData().add(data);
}
}
}
the only difference it has is the data.setIdx(i++); Please let me know if there is anything i can do to reduce number of lines
You could factor out a method that takes a FormInstanceControl and a AjaxControlBean as arguments. Then you've got all you need:
private void addBeanData( FormInstanceControl control, AjaxControlBean controlBean) {
int i = 0;
for (String value : controlBean.getValues()) {
FormInstanceData data = new FormInstanceData();
data.setControl(control);
data.setType(FormInstanceData.TYPE_TEXT);
data.setText(value);
data.setIdx(i++);
control.getData().add(data);
}
}
This assumes, the first snippet doesn't break if the Idx is set, even if it's not done there in the original code.
Usage: Where before you had the for-loops, you just do addBeanData( control, controlBean );

Pass parameter value from my implementation service to my RestController java springboot

I'm having a trouble passing the value of error i get when im returning the results of a table.
I have a method in my ServiceImpl class which return results for the table and also counts the amount of errors.
public List<Flow> getAllProcessContextWithCriteriaAndFlowCode(
String startDate, String endDate, String flowCode) {
List<FlowDto> flowDtos = new ArrayList<>(500);
flowDtos = processContextRepository
.fetch(startDate,
endDate, flowCode);
List<Flow> flows = new ArrayList();
// bodyguard
if (flowDtos == null || flowDtos.size() == 0) {
return flows;
}
int counter = 0;
StringBuilder idFonctionnelBuilder = new StringBuilder();
FlowDto currentFlowDto = null;
FlowState flowState = new FlowState();
FlowDto nextFlowDto = null;
Flow flowTemp = null;
Map<String, String> mapFlowIdsAndIdF = new HashMap<>();
int iNbreError = 0;
String sTempError = "";
for (int i = 0; i < flowDtos.size(); i++) {
currentFlowDto = flowDtos.get(i);
if ((i + 1) < flowDtos.size()) {
nextFlowDto = flowDtos.get(i + 1);
if (((nextFlowDto.getFlowId()
.equals(currentFlowDto.getFlowId())))) {
idFonctionnelBuilder.append(currentFlowDto.getIdf() + ", ");
continue;
} else {
flowTemp = new Flow();
flowTemp.setFlowId(currentFlowDto.getFlowId());
flowTemp.setLogRole(currentFlowDto.getLogRole());
Date date = null;
try {
date = inputFormat.parse(currentFlowDto
.getContextTime());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flowTemp.setContextTime(outputFormat.format(date));
if (currentFlowDto.getLogRole() != null) {
iNbreError++;
flowTemp.setNbreError(iNbreError);
} else {
flowTemp.setNbreError(iNbreError);
}
flowTemp.setNbreError(iNbreError);
flows.add(flowTemp);
}
} else {
flowTemp = new Flow();
if (currentFlowDto.getLogRole() != null) {
iNbreError++;
flowTemp.setNbreError(iNbreError);
} else {
flowTemp.setNbreError(iNbreError);
}
flowTemp.setContextTime(outputFormat.format(date));
flows.add(flowTemp);
}
}
LOGGER.info("[ getAllProcessContextWithCriteriaAndFlowCode ] iNbreError : "
+ iNbreError);
getNbreError(iNbreError);
return flows;
}
Then i have another method in the same class ServiceImpl who get the number of errors and set it in a variable, the result print is always the right one here.
public int getNbreError( int iNbreError){
System.out.println("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
System.out.println(iNbreError);
setCountError(iNbreError);
System.out.println("HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH");
System.out.println(countError);
return countError;
}
What i want to do is send this value(counterror) to my RestController which is in another class called RestController so i can send it to my angular front
#GetMapping(value = "/nbreError")
public int getCountError() {
FMServiceImpl flows = new FMServiceImpl();
int countError = 0;
int iNbreError = 0;
return fmService.getNbreError( iNbreError);
}
}
Actually the result is always 0.
Thanks for your any help or advice :)
Don't use getMethod to modify data, check principle Command–query separation (CQS)
Don't create FMServiceImpl manually, Inject FMServiceImpl as dependence to your controller. in spring, Service keeps the state by default.

Method that doesn't allow more participants than the maximum and same number of registration

I have a issue here. I need to create this method:
Method: registraParticipante (Aluno alu) that will receive by parameter one
student(Aluno) and add to the participant(participante) array. The method should also implement the following rules:
control not to allow more participants to register which was defined in the attribute: Maximum number of participants(qtMaxParticipantes);
not allow registration of a participant who has the same number of registration(int matricula) of an already registered participant.
I have the superclass Usuario (means User) with the int matricula in it
and the subclass Aluno (means student)
PROBLEM SOLVED - Thanks Andre.
public void registraParticipante(Aluno alu) {
if (!matriculaJaExistente(alu))
{
for (int i = 0; i < listaDeParticipantes.length; i++)
{
if (listaDeParticipantes[i] == null)
{
listaDeParticipantes[i] = alu;
break;
} else {
System.out.println("Número maximo de participante atingido.");
}
}
} else {
System.out.println("Aluno já matriculado.");
}
}
public boolean matriculaJaExistente(Aluno a)
{
boolean resultado = false;
for (int i = 0; i < listaDeParticipantes.length; i++)
{if (listaDeParticipantes[i].getMatricula() == a.getMatricula())
{
resultado = true;
}
else
{
resultado = false;
}
}
return resultado ;
}
I don't know if you necessarily have to use an array, so I guess that using a List would be the best solution, than, your code would look like this:
List<Aluno> alunosList = new ArrayList();
private int maxParticipantes = 5; // arbitrary number
public void registraParticipante(Aluno a) {
if (alunosList.size() > maxParticipantes || alunoJaRegistrado(a)) {
System.out.println("Can't add this aluno");
} else {
alunosList.add(a);
}
}
public boolean alunoJaRegistrado(Aluno aluno) {
boolean result;
for (Aluno a : alunosList) { // this goes through each aluno on the list
if (a.getMatricula() == aluno.getMatricula) {
result = true;
break;
} else result = false;
}
return result;
}

Perform Sorting of JTable list in java class with JSorting

I have a problem and i m struggling to solve it with no luck , so i was wondering if anyone can help me, and any help would be really appreciated.
I have a java class to perform operations (in an html page in the front) such as filtering, paging and now i want to perform Sorting with JSorting but i cant do it, my java code is the following were is working so far the filtering and paging.. but i have tried many methods to perform sorting but netbeans always says to me not suitable method.. is anyone knows a method for sorting in my code ? please some help Guys,, Thank you in advance for the effort.. here is my code ,, i have removed my method for sorting cause is not working.. :(
/**
* Retrieves all the topics (backend - admin side)
*
* #param jtStartIndex Indicates the first record of paging
* #param jtPageSize Number of records to show in each page
* #param topic
* #param forumId
* #param status
* #param search
* #return an instance of javax.ws.rs.core.Response
*/
#RolesAllowed({AllConstants.USER_ROLE_ADMIN})
#Path("/getTopics")
#GET
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response getTopics(#QueryParam("jtStartIndex") int jtStartIndex,
#QueryParam("jtPageSize") int jtPageSize,
#QueryParam("topic") String topic,
#QueryParam("forum") int forumId,
#QueryParam("state") int status,
#QueryParam("jtSorting") String jtSorting,
#QueryParam("search") int search) {
try {
EntityManager em = JpaUtils.getEntityManager();
List<JforumTopic> topicEntities;
//Filtering
if (search == 1) {
if (topic == null) {
topic = "";
}
StringBuilder sb = new StringBuilder();
sb.append("SELECT t FROM JforumTopic t WHERE LOWER(t.topicTitle) LIKE :topicTitle ");
if (forumId > 0) {
sb.append(" AND t.forumId = :forumId ");
}
if (status > -1) {
sb.append(" AND t.topicStatus = :topicStatus ");
}
Query query = em.createQuery(sb.toString());
query.setParameter("topicTitle", "%" + topic.toLowerCase() + "%");
if (forumId > 0) {
query.setParameter("forumId", forumId);
}
if (status > -1) {
query.setParameter("topicStatus", status);
}
topicEntities = query.getResultList();
} else {
TypedQuery<JforumTopic> query = em.createNamedQuery("JforumTopic.findAll", JforumTopic.class);
topicEntities = query.getResultList();
}
//Paging
PagingHelper<JforumTopic> ph = new PagingHelper<JforumTopic>(jtStartIndex, jtPageSize, topicEntities);
topicEntities = ph.getSublist();
String jsonFinal = ph.getJson(topicEntities);
return Response.status(Response.Status.OK).entity(jsonFinal).build();
} catch (Exception ex) {
logger.log(Level.SEVERE, "ForumResource.getTopics() threw exception: ", ex);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
the field in my page that i want to make sorting is e.g. relatedId so using Comparators my code will be like that,
//Sorting
//------------------------------------------------------------------
if (jtSorting != null && !jtSorting.isEmpty()) {
String keyCompared = "";
MyComparators.enumSortingType order = MyComparators.enumSortingType.ASC;
MyComparators.enumDatatype datatype = MyComparators.enumDatatype.STRING;
if (jtSorting.equals("relatedId ASC")) {
keyCompared = "relatedId";
order = MyComparators.enumSortingType.ASC;
datatype = MyComparators.enumDatatype.STRING;
}
if (jtSorting.equals("relatedId DESC")) {
keyCompared = "relatedId";
order = MyComparators.enumSortingType.DESC;
datatype = MyComparators.enumDatatype.STRING;
}
MyComparators.MapComparator comparator = new MyComparators.MapComparator(keyCompared, order, datatype);
Collections.sort(list, comparator);
}
//-------------------------------------------------------------------
but i dont know how to create the list... please guys some help,, thank you..
i made it here is my code in case anyone need it the sorting!!!! Thank you for reading!!!
/**
* Retrieves all the topics (backend - admin side)
*
* #param jtStartIndex Indicates the first record of paging
* #param jtPageSize Number of records to show in each page
* #param topic
* #param forumId
* #param status
* #param search
* #return an instance of javax.ws.rs.core.Response
*/
#RolesAllowed({AllConstants.USER_ROLE_ADMIN})
#Path("/getTopics")
#GET
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response getTopics(#QueryParam("jtStartIndex") int jtStartIndex,
#QueryParam("jtPageSize") int jtPageSize,
#QueryParam("topic") String topic,
#QueryParam("forum") int forumId,
#QueryParam("state") int status,
#QueryParam("jtSorting") String jtSorting,
#QueryParam("search") int search) {
try {
EntityManager em = JpaUtils.getEntityManager();
List<JforumTopic> topicEntities;
//Filtering
if (search == 1) {
if (topic == null) {
topic = "";
}
StringBuilder sb = new StringBuilder();
sb.append("SELECT t FROM JforumTopic t WHERE LOWER(t.topicTitle) LIKE :topicTitle ");
if (forumId > 0) {
sb.append(" AND t.forumId = :forumId ");
}
if (status > -1) {
sb.append(" AND t.topicStatus = :topicStatus ");
}
Query query = em.createQuery(sb.toString());
query.setParameter("topicTitle", "%" + topic.toLowerCase() + "%");
if (forumId > 0) {
query.setParameter("forumId", forumId);
}
if (status > -1) {
query.setParameter("topicStatus", status);
}
topicEntities = query.getResultList();
} else {
TypedQuery<JforumTopic> query = em.createNamedQuery("JforumTopic.findAll", JforumTopic.class);
topicEntities = query.getResultList();
}
//Sorting
if (jtSorting != null && !jtSorting.isEmpty()) {
if (jtSorting.equals("relatedId ASC")) {
Collections.sort(topicEntities, new Comparator<JforumTopic>(){
#Override
public int compare(JforumTopic top1, JforumTopic top2) {
return top1.getRelatedId().compareTo(top2.getRelatedId());
}
});
}
if(jtSorting.equals("relatedId DESC")) {
Collections.sort(topicEntities, new Comparator<JforumTopic>(){
#Override
public int compare(JforumTopic top1, JforumTopic top2) {
return top2.getRelatedId().compareTo(top1.getRelatedId());
}
});
}
if (jtSorting.equals("relatedTitle ASC")) {
Collections.sort(topicEntities, new Comparator<JforumTopic>(){
#Override
public int compare(JforumTopic top3, JforumTopic top4) {
return top3.getRelatedTitle().compareTo(top4.getRelatedTitle());
}
});
}
if(jtSorting.equals("relatedTitle DESC")) {
Collections.sort(topicEntities, new Comparator<JforumTopic>(){
#Override
public int compare(JforumTopic top3, JforumTopic top4) {
return top4.getRelatedTitle().compareTo(top3.getRelatedTitle());
}
});
}
}
// end of sorting
//Paging
PagingHelper<JforumTopic> ph = new PagingHelper<JforumTopic>(jtStartIndex, jtPageSize, topicEntities);
topicEntities = ph.getSublist();
String jsonFinal = ph.getJson(topicEntities);
return Response.status(Response.Status.OK).entity(jsonFinal).build();
} catch (Exception ex) {
logger.log(Level.SEVERE, "ForumResource.getTopics() threw exception: ", ex);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
/**

Categories